歸併排序的一種實現



歸併排序是建立在歸併操作上的一種有效的排序算法,該算法是採用分治法(Divide and Conquer)的一個非常典型的應用。將已有序的子序列合併,得到完全有序的序列;即先使每個子序列有序,再使子序列段間有序。若將兩個有序表合併成一個有序表,稱爲二路歸併。

看到一篇博客講的蠻好的,動態圖很生動,下面是鏈接:

http://blog.csdn.net/wu_lai_314/article/details/8450933


博主同時還在另外一篇博文中介紹了一種改進算法,不過代碼雖然能得到正確結果,但是由於程序邏輯不對,實際排序是通過插入排序法進行排序的,其歸併排序算是繞了一圈沒有解決問題。其鏈接如下:

http://blog.csdn.net/wu_lai_314/article/details/8452526


這裏是我進行修改後的代碼:

#define  M 16
#include<iostream>
#include <time.h>
#include<iomanip>

using namespace std;

void insertSort(int *a, int left, int right){
	int tmp;
	int i, j;
	for (i = left + 1; i <= right; i++){//外層循環是從第二個元素開始的
		if (a[i]<a[i - 1]){
			tmp = a[i];
			j = i - 1;
			do{
				a[j + 1] = a[j--];
			} while (j >= left && tmp < a[j]);
			a[j + 1] = tmp;
		}
	}
}


void improvedMerge(int *a, int left, int mid, int right){
	int s1 = left;//s1,s2 是檢測指針,t是存放指針
	int s2 = right;
	int t = left, k;
	int *b = new int[right];

	for (k = left; k <= mid; k++)//正向複製
		b[k] = a[k];

	for (k = mid + 1; k <= right; k++)//反向複製
		b[right + mid + 1 - k] = a[k];
	while (t <= right){//歸併過程
		if (b[s1] <= b[s2]) a[t++] = b[s1++];
		else	a[t++] = b[s2--];
	}

}

void doSort(int *a, int left, int right){
	if (left >= right) return;
	if (right - left + 1 < M)
	{
		insertSort(a, left, right);//序列長度小於M時候,進行插入排序,再跳出循環
		return;
	}
	int mid = (left + right) / 2;//從中間劃分兩個子序列
	doSort(a, left, mid);//從左側子序列進行遞歸排序
	doSort(a, mid + 1, right);//從右側子序列進行遞歸排序
	improvedMerge(a, left, mid, right);//合併
}




void main(){
	int a[100];
	srand((unsigned int)time(NULL));
	for (int i = 0; i<100; i++)
		a[i] = rand();

	doSort(a, 0, 99);
	for (int i = 0; i<100; i++){
		if (i % 7 == 0 && i != 0)
			cout << endl;
		cout << setw(10) << a[i] << " ";
	}
	cout << endl;
	getchar();


}

發佈了31 篇原創文章 · 獲贊 19 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章