2014.06.17 04:34
简介:
归并排序是分治法的一个好例子,属于基于比较的内部/外部排序算法。普通的归并算法具有O(n * log(n))的时间和O(n)的空间复杂度。就地归并算法能帮助降低额外空间开销,使得归并排序更高效。
描述:
分治法的思路就是先把大问题化为多个小问题,都解决了以后进行合并处理。用在归并排序上,就是先排序几个片段,然后把排好序的片段拼成一整段。有了O(n)的额外空间,代码就简单得不需要任何解释了。相比之下,就地归并算法好像有些难理解,等我学习了STL的<algorithm>算法库以后,一定会专门写一篇学习就地归并的博文。
归并排序之所以可以轻松应用到外部排序上,是因为归并排序的归并过程是顺序扫描的,可以用来处理顺序存储的文件,多路归并还可以用多线程或是并行计算来加速,这样处理大文件就方便了。而想随机访问一个文件,就没那么快了。
实现:
1 // My implementation for merge sort. 2 #include <iostream> 3 #include <vector> 4 using namespace std; 5 6 void mergeSortRecursive(vector<int> &v, vector<int> &temp, int left, int right) 7 { 8 if (right - left < 1) { 9 return; 10 } 11 int mid = left + (right - left) / 2; 12 mergeSortRecursive(v, temp, left, mid); 13 mergeSortRecursive(v, temp, mid + 1, right); 14 15 int i, j, k; 16 i = left; 17 j = mid + 1; 18 k = left; 19 while (i <= mid && j <= right) { 20 if (v[i] < v[j]) { 21 temp[k++] = v[i++]; 22 } else { 23 temp[k++] = v[j++]; 24 } 25 } 26 while (i <= mid) { 27 temp[k++] = v[i++]; 28 } 29 while (j <= right) { 30 temp[k++] = v[j++]; 31 } 32 for (i = left; i <= right; ++i) { 33 v[i] = temp[i]; 34 } 35 } 36 37 void mergeSort(vector<int> &v) 38 { 39 int n; 40 vector<int> temp; 41 42 n = (int)v.size(); 43 temp.resize(n); 44 mergeSortRecursive(v, temp, 0, n - 1); 45 temp.clear(); 46 } 47 48 int main() 49 { 50 vector<int> v; 51 int n, i; 52 53 while (cin >> n && n > 0) { 54 v.resize(n); 55 for (i = 0; i < n; ++i) { 56 cin >> v[i]; 57 } 58 mergeSort(v); 59 for (i = 0; i < n; ++i) { 60 cout << v[i] << ' '; 61 } 62 cout << endl; 63 } 64 65 return 0; 66 }