归并排序

介绍以下两种做法,第一种比较清晰

//将数组中l1 r1, l2 r2的数组进行排序,存放在inputList中 
void mergeTwo(int* inputLlist, int left1, int right1, int left2, int right2) 
{
    int i= left1;
    int j = left2;
    int n = right1 - left1 + 1 + right2 - left2 + 1;
    int* tmpList = new int[n];
    int k = 0;
    while(i <= right1 && j <= right2)
    {
        if(inputLlist[i] < inputLlist[j])
        {
            tmpList[k++] = inputLlist[i++];
        }
        else
        {
            tmpList[k++] = inputLlist[j++];
        }
    }
    while(i <= right1)
    {
        tmpList[k++] = inputLlist[i++];
    }
    while(j <= right2)
    {
        tmpList[k++] = inputLlist[j++];
    }
    for(int i = 0; i < n; ++i)
    {
        inputLlist[left1 + i] = tmpList[i];
    }
} 
void mergeRecursive(int* inputList, int start, int end)
{
    if(start < end)
    {
        int mid = (start + end) >> 1;
        mergeRecursive(inputList, start, mid);
        mergeRecursive(inputList, mid + 1, end);
        mergeTwo(inputList, start, mid, mid + 1, end);
    }    
}
int main()
{
/*
    int a[] = {23, 47, 81, 95, 7, 14, 39, 55, 62, 74};
    int b[10] = {0};
    merge(a, b, 0, 3, 10);
    for(int i = 0; i < 10; ++i)
    {
        cout<<b[i] << " ";
    }
    cout << endl;*/
    
    int m[] = {26, 5, 77, 1, 61, 11, 59, 15, 48, 19};
    int n[10] = {0};
    mergePass(m, n, 10, 1);
    for(int i = 0; i < 10; ++i)
    {
        cout<<n[i] << " ";
    }
    cout << endl;
    
    mergePass(n, m, 10, 2);
    for(int i = 0; i < 10; ++i)
    {
        cout<<m[i] << " ";
    }
    cout << endl;
    
    mergePass(m, n, 10, 4);
    for(int i = 0; i < 10; ++i)
    {
        cout<<n[i] << " ";
    }
    cout << endl;
        
    mergePass(n, m, 10, 8);
    for(int i = 0; i < 10; ++i)
    {
        cout<<m[i] << " ";
    }
    cout << endl;
    cout << "================test result is =================" << endl;
    int a[] = {26, 5, 77, 1, 61, 11, 59, 15, 48, 19};
    mergeSort(a, 10);
    for(int i = 0; i < 10; ++i)
    {
        cout<<a[i] << " ";
    }
    cout << endl;
    
    int b[] = {26, 5, 77, 1, 61, 11, 59, 15, 48, 19};
    mergeRecursive(b, 0, 9);
    cout << "================mergeRecursive result is =================" << endl;
    for(int i = 0; i < 10; ++i)
    {
        cout<<b[i] << " ";
    }
    cout << endl;    
    cout<<"hello" << endl;
    return 0;
}

第二种:

#include<iostream>
#include<algorithm>
using namespace std;

void merge(int* oriList, int * resultList, int firstBegin, int firstEnd, int secondEnd)
{
    int i, j, resultIndex;
    for(i = firstBegin, j = firstEnd + 1, resultIndex = firstBegin; i <= firstEnd && j < secondEnd;  ++resultIndex)    
    {
        if(oriList[i] < oriList[j])
        {
            resultList[resultIndex] = oriList[i];
            i++;
        }
        else
        {
            resultList[resultIndex] = oriList[j];
            j++;
        }
    }
    copy(oriList + i, oriList + firstEnd + 1, resultList + resultIndex);
    copy(oriList + j, oriList + secondEnd, resultList + resultIndex);
}

void mergePass(int* oriList, int* resultList, const int len, int step)
{
    int i;
    for(i = 0; i < len - 2*step; i = i + 2*step)    
    {
        merge(oriList, resultList, i, i + step - 1, i + 2*step);
    }
    //落单的在最后一次将其合并进来,最后一次的条件是没有进入上面的for循环,也就是 
    if(i < len - step)
    {
        merge(oriList, resultList, i, i + step - 1, len);
    }
    else
    {
        copy(oriList + i, oriList + len, resultList + i);
    }
}
void mergeSort(int* oriList, int n)
{
    int* tmpList = new int[n];    
    for(int i = 1; i < n; i = 2*i)//注意这里是以1开始的,否则会进入死循环 ,利用两次调用,巧妙地将值放在了oriList中 
    {
        mergePass(oriList, tmpList, n, i);
        i = 2*i;
        mergePass(tmpList, oriList, n, i);
    }
    delete []tmpList;
}

 

posted @ 2019-06-23 11:57  rainsoul  Views(195)  Comments(0Edit  收藏  举报