《数据结构与算法分析:C语言描述》复习——第六章“排序”——归并排序

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 }

 

你可能感兴趣的:(数据结构与算法)