1. 程式人生 > >算法之歸並排序

算法之歸並排序

new 復制 ont -- 選擇 delet 技術 roc alt

原博文

歸並:將兩個或兩個以上的有序表組合成一個新有序表。

歸並操作的步驟:

  1. 申請空間,使其大小為兩個已經排序序列之和,該空間用來存放合並後的序列

  2. 設定兩個指針,最初位置分別為兩個已經排序序列的起始位置

  3. 比較兩個指針所指向的元素,選擇相對小的元素放入到合並空間,並移動指針到下一位置

  4. 重復步驟3直到某一指針超出序列尾

  5. 將另一序列剩下的所有元素直接復制到合並序列尾

歸並圖解:

技術分享

代碼實現:

#include <iostream>
using namespace std;

//將數組 a[low,mid] 與 a(mid,high] 合並(歸並)
void Merge(int * a, int low, int mid, int high, int * temp)
{
    int i,j,k;
    i = low;
    j = mid + 1;//避免重復比較a[mid]
    k = 0;
    while (i <= mid && j <= high)//數組a[low,mid]與數組(mid,high]均沒有全部歸入數組temp中去
    {
        if(a[i] <= a[j])        //如果a[i]小於等於a[j]
            temp[k++] = a[i++]; //則將a[i]的值賦給temp[k],之後i,k各加一,表示後移一位
        else
            temp[k++] = a[j++]; //否則,將a[j]的值賦給temp[k],j,k各加一
    }
    while(i <= mid)             //表示數組a(mid,high]已經全部歸入temp數組中去了,而數組a[low,mid]還有剩余
        temp[k++] = a[i++];     //將數組a[low,mid]剩下的值,逐一歸入數組temp
    while(j <= high)           //表示數組a[low,mid]已經全部歸入到temp數組中去了,而數組(mid,high]還有剩余
        temp[k++] = a[j++];     //將數組a(mid,high]剩下的值,逐一歸入數組temp

    for (i = 0; i < k; i++)     //將歸並後的數組的值逐一賦給數組a[low,high]
        a[low+i] = temp[i];     //註意,應從a[low+i]開始賦值
}

//二路歸並(遞歸實現)
void MergeSort(int * a, int low, int high, int * temp)
{
    if (low < high)
    {
        int mid = (low + high)/2;
        MergeSort(a,low,mid,temp);      //左邊有序
        MergeSort(a,mid+1,high,temp);   //右邊有序
        Merge(a,low,mid,high,temp);     //再將兩個有序序列合並
    }
}

/*----------測試代碼----------*/
int main()
{
    int a[] = {2,23,34,43,45,6,7,8,5,4,56,78,80,211,222,444,111};
    int La = sizeof(a)/sizeof(a[0]);
    int * p = new int[La];
    MergeSort(a,0,La-1,p);
    for (int i = 0; i < La; i++)
    {
        cout<<a[i]<<‘ ‘;
    }
    cout<<endl;
    delete []p;
}

算法之歸並排序