二分歸併排序

二分歸併排序是歸併排序(合併排序)裏面最簡單的一種實現。

             這個算法的主要思想是:將被排序的數組劃分成相等的兩個子數組,然後遞歸使用同樣的算法分別對兩個子數組排序。最好將兩個排好序的子數組歸併成一個數組。

       歸併的過程如下:假設兩個子數組是A和B,它們的元素都按照從小到大的順序排列。將A與B歸併後的數組記作C。設定兩個指針p1,p2,初始分別指向A和B的最小元素。歸併時只需比較p1,p2指向的元素,哪個元素小,就把它從原來的數組移到C,原來指向它的指針向後移動一個位置。如果A和B中有一個數組的元素已經被全部移走,那麼比較過程結束,剩下的工作就是將B中剩下的元素順序移動C的後面。

       考慮10個數的數組:1,5,7,8,2,4,6,9,10,3,使用歸併排序算法,首先劃分成兩個子數組,即A=[1,5,7,8,2],B=[4,6,9,10,3]. 然後對於A和B分別調用同樣的算法進行排序。假設A和B已經完成排序,即A=[1,2,5,7,8],B=[3,4,6,9,10],下面進行歸併。首先1與3 比較,拿走1;接着2與3比較,拿走2;再接着5和3比較,拿走3,.........繼續下去,依次拿走4,5,6,7,8.這是A數組已經空了,比較結束,把B中剩下的9和10順序放到歸併後的數組中

       假設輸入規模爲n,最好情況下,需要比較n/2次,最壞情況下(n-1)次。時間複雜度就不推導了,爲nlogn。

下面給出合併兩個數組的代碼

//將有序數組a[]和b[]合併到c[]中
void merge(int a[], int n, int b[], int m, int c[])
{
	int i, j, k;

	i = j = k = 0;
	while (i < n && j < m)
	{
		if (a[i] < b[j])
			c[k++] = a[i++];
		else
			c[k++] = b[j++]; 
	}

	while (i < n)
		c[k++] = a[i++];

	while (j < m)
		c[k++] = b[j++];
}
可以將A,B組各自再分成二組。依次類推,當分出來的小組只有一個數據時,可以認爲這個小組組內已經達到了有序,然後再合併相鄰的二個小組就可以了。這樣通過先遞的分解數列,再合數列就完成了歸併排序

代碼如下

void mergearray(int a[], int first, int mid, int last, int temp[])  
{  
    int i = first, j = mid + 1;  
    int m = mid,   n = last;  
    int k = 0;  
      
    while (i <= m && j <= n)  
    {  
        if (a[i] <= a[j])  
            temp[k++] = a[i++];  
        else  
            temp[k++] = a[j++];  
    }  
      
    while (i <= m)  
        temp[k++] = a[i++];  
      
    while (j <= n)  
        temp[k++] = a[j++];  
      
    for (i = 0; i < k; i++)  
        a[first + i] = temp[i];  
}  
void mergesort(int a[], int first, int last, int temp[])  
{  
    if (first < last)  
    {  
        int mid = (first + last) / 2;  
        mergesort(a, first, mid, temp);    //左邊有序  
        mergesort(a, mid + 1, last, temp); //右邊有序  
        mergearray(a, first, mid, last, temp); //再將二個有序數列合併  
    }  
}  
  
bool MergeSort(int a[], int n)  
{  
    int *p = new int[n];  
    if (p == NULL)  
        return false;  
    mergesort(a, 0, n - 1, p);  
    delete[] p;  
    return true;  
}  


       


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章