歸併排序(merge sort)完全遵循上述分治法三個步驟:
1、分解:將要排序的n個元素的序列分解成兩個具有n/2個元素的子串行;
2、解決:使用歸併排序分別遞迴地排序兩個子串行;
3、合併:合併兩個已排序的子串行,產生原問題的解。
所以說歸併排序一種分治演算法的典型應用。
歸併排序過程動態演示
時間複雜度是o(
nlogn)
,空間復制度為o(
n)(歸併排序的最大缺陷)。歸併排序在資料量比較大的時候也有較為出色的表現(效率上),但是,其空間複雜度o(n)使得在資料量特別大的時候(例如,1千萬資料)幾乎不可接受。而且,考慮到有的機器記憶體本身就比較小。總結來說,歸併排序是一種占用記憶體,但卻效率高且穩定的演算法。
void merge_array(int arr, int tmp, int left, int mid, int right)
while(i <= mid) //拷貝剩下的左半部分
tmp[index++] = arr[i++];
while(j <= right) //拷貝剩下的右半部分
tmp[index++] = arr[j++];
memcpy(arr + left, tmp, (right - left + 1) * sizeof(int));
}void merge_sort(int arr, int tmp, int left, int right)
}void merge_sort(int arr, int len)
#include
#include
#include
#include
using namespace std;
#define arraysize 100000
void swap(int *x, int *y)
void bubble_sort(int arr, int len)
}void bubble_sort1(int arr, int len)
}}void bubble_sort2(int arr, int len)
}void slect_sort(int arr, int len)
if(i != min_index)
swap(arr[i],arr[min_index]);
}}void insert_sort(int arr, int len)
arr[j] = key;
}}void shell_sort(int arr, int len)
*/int j = i;
while(j >= increment && arr[j-increment] > key)
arr[j] = key;
}increment /= 2;
}}void shell_sort1(int arr, int len)
arr[j] = key;}}
}void shell_sort2(int arr, int len)
*/int j = i;
while(j >= increment && arr[j-increment] > key)
arr[j] = key;
}index -= 1;
increment = ( pow(3.0, index) - 1 ) / 2;
}}void heap_adjust(int arr, int
index, int len)
else
break;
}}void heap_adjust2(int arr, int
index, int len)
}void build_maxheap(int arr, int len)
}void heap_sort(int arr, int len)
}void print_array(int arr, int len)
cout << endl;
}void merge_array(int arr, int tmp, int left, int mid, int right)
while(i <= mid)
tmp[index++] = arr[i++];
while(j <= right)
tmp[index++] = arr[j++];
memcpy(arr + left, tmp, (right - left + 1) * sizeof(int));
}void merge_sort(int arr, int tmp, int left, int right)
}void merge_sort(int arr, int len)
int main(int argc, char const *argv)
memcpy(array1, array, arraysize * sizeof(array1[0]));
memcpy(array2, array, arraysize * sizeof(array2[0]));
// print_array(array, arraysize);
/* begin = clock();
bubble_sort2(array, arraysize);
end = clock();
cout << "bubble_sort runtime: " << double(end - begin) / clocks_per_sec << "s" << endl;
begin = clock();
slect_sort(array1, arraysize);
end = clock();
cout << "slect_sort runtime: " << double(end - begin) / clocks_per_sec << "s" << endl;
begin = clock();
insert_sort(array2, arraysize);
end = clock();
cout << "insert_sort runtime: " << double(end - begin) / clocks_per_sec << "s" << endl;*/
begin = clock();
shell_sort2(array, arraysize);
end = clock();
cout << "shell_sort2 runtime: "
<< double(end - begin) / clocks_per_sec << "s"
<< endl;
begin = clock();
heap_sort(array1, arraysize);
end = clock();
cout << "heap_sort runtime: "
<< double(end - begin) / clocks_per_sec << "s"
<< endl;
begin = clock();
merge_sort(array2, arraysize);
end = clock();
cout << "merge_sort runtime: "
<< double(end - begin) / clocks_per_sec << "s"
<< endl;
//print_array(array2, arraysize);
return
0;}
執行結果如下:
shell_sort2 runtime: 0.026s
heap_sort runtime: 0.004s
merge_sort runtime: 0.014s
排序4 歸併排序
3.海量資料的排序問題 歸併排序 merge sort 是建立在歸併操作上的一種有效的排序演算法,該演算法是採用分治法 divide and conquer 的乙個非常典型的應用。歸併排序適合於外部排序,也可以適用於鍊錶排序。外部排序 指的是資料儲存在磁碟上。鍊錶排序 希爾 堆排序 快速排序等均不適...
4 歸併排序
一 基本思想 對於乙個待排序的序列,遞迴地將前半部分資料和後半部分資料各自歸併排序,得到排序後的兩部分資料,然後合併這兩個部分。歸併演算法採用分而治之的策略 a.將問題分成一些小的問題然後遞迴求解 b.將分的階段解得的各個答案 修補 到一起。可以看到這種結構很像一棵完全二叉樹,故我們可以採用遞迴來實...
4 內部排序 歸併排序
歸併排序 歸併排序和快速排序這兩種演算法都採用了分治的思想,且速度僅次於 快速排序 為穩定排序演算法,一般用於對總體無序,但是各子項相對有序的 數列,其具體思想如下 1 將序列每相鄰兩個數字進行歸併操作 merge 形成 n 2 個序列,排序後每個序列包含兩個元素 2 將上述序列再次歸併操作,形成 ...