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 }

 

 posted on 2014-06-17 04:46  zhuli19901106  阅读(501)  评论(0编辑  收藏  举报