递归归并排序 二路归并排序

五迷三道 提交于 2020-03-31 15:34:53

归并算法的两种方法:

1、使用分治法的递归归并算法:

/*递归归并排序
 *将有二个有序数列list[first...mid]和list[mid+1,...last]合并
 *list:待排序数组
 *first:子序列1的下界
 *mid:子序列1的上界
 *last:子序列2的上界
 *temp:临时保存数组
*/
void Merge(element list[], int first, int mid, int last, element temp[])
{
    int i = first, j = mid + 1;
    int m = mid,   n = last;
    int k = 0;
    
    while (i <= m && j <= n)
    {
        if (list[i] < list[j])
            temp[k++] = list[i++];
        else
            temp[k++] = list[j++];
    }
    
    while (i <= m)
        temp[k++] = list[i++];
    
    while (j <= n)
        temp[k++] = list[j++];
    
    for (i = 0; i < k; i++)
        list[first + i] = temp[i];

    return ;
}
/*递归归并排序
 *分治,完成递归归并
 *list:待排序数组
 *first:list下界
 *last:list上界
 *temp:临时保存数组
*/
void mergesort(element list[], int first, int last, element temp[])
{
    if (first < last)
    {
        int mid = (first + last) / 2;
        mergesort(list, first, mid, temp);    //左边有序
        mergesort(list, mid + 1, last, temp); //右边有序
        Merge(list, first, mid, last, temp); //再将二个有序数列合并
    }
    return ;
}
/*递归归并排序
 *list:待排序数组
 *n:为数组长度
*/
bool MergeSort(element list[], int n)
{
    element *p = new element[n];//空间复杂度为O(n)
    if (p == NULL)
        exit(1);
        
    mergesort(list, 0, n - 1, p);
    
    delete[] p;
    return true;
}

2、二路归并算法:

/*归并算法二,二路归并
 *list:待排序数组
 *n:为数组长度
 *temp:临时保存数组
 *k:为有序子数组的长度,一次二路归并排序后有序子序列存于temp数组中
*/
void Merge2(element list[], int n, element temp[], int k)
{
    int i, j;
    int m=0;

    int low1=0;//第一有序的下界
    int up1, low2, up2;//第一有序的上界,第二有序的下界,第二有序的上界

    /*将原始数组中足够分为两组的数据元素二路归并存放到数组temp中*/
    while(low1+k < n-1)
    {
        low2 = low1+k;
        up1  = low2-1;

        up2 =(low2+k-1 < n-1) ? low2+k-1:n-1;

        for(i=low1, j=low2; i<=up1 && j <=up2; )
        {
            if (list[i] <= list[j])
                temp[m++] = list[i++];
            else
                temp[m++] = list[j++];
        }

        while (i <= up1)
            temp[m++] = list[i++];
    
        while (j <= up2)
            temp[m++] = list[j++];

        low1 = up2+1;
    }

    /*将原始数组中只够一组的数据元素顺序存放到数组temp中*/
    i=low1;
    while(i<n)
    {
        temp[m++] = list[i++];
    }
    return;
}
/*二路归并排序
 *list:待排序数组
 *n:为数组长度
*/
bool MergeSort2(element list[], int n)
{
    element *p = new element[n];//空间复杂度为O(n)
    if (p == NULL)
        exit(1);

    int k=1;//二路归并长度从1开始
    int i=0;

    while(k<n)
    {
        Merge2(list, n, p, k);//每次归并后保存在p中
        for(i=0; i<n; i++)
            list[i] = p[i];//从p中拷贝到list中

        k *=2;//归并长度加倍
    }
    delete[] p;
    return true;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!