+ -
当前位置:首页 → 问答吧 → 归并排序(有代码)的时间复杂度O(nlogn)是怎么算出来的呢?(即关于时间复杂度的分析)

归并排序(有代码)的时间复杂度O(nlogn)是怎么算出来的呢?(即关于时间复杂度的分析)

时间:2010-08-31

来源:互联网

本帖最后由 glq2000 于 2010-08-31 20:42 编辑

归并排序在平均情况和最坏情况下的时间复杂度都是O(nlogn),但这个是怎么算出来的呢? 希望懂的的同学 说下拉 十分感谢!!!!


下面是我写的归并排序的代码,用递归实现的,主要函数是MergeSort(), 代码如下(若感觉下列代码格式不够良好,请到这里查看:
http://fayaa.com/code/view/13301/
):
  1. /*
  2. * =====================================================================================
  3. *
  4. *       Filename:  MergeSort.cpp
  5. *
  6. *    Description:  MergeSort,归并排序,用递归实现
  7. *
  8. *        Version:  1.0
  9. *        Created:  2010年08月31日 14时47分14秒
  10. *       Revision:  none
  11. *       Compiler:  gcc
  12. *
  13. *         Author:  glq2000 (), [email protected]
  14. *        Company:  HUE ISRC
  15. *
  16. * =====================================================================================
  17. */
  18. #include <iostream>
  19. using namespace std;
  20. #define N 11
  21. int array[N] = { 4, 67, 456, 23, 1, 78, 26, 222, 34, 432, 12 }; //待排序数组
  22. int other[N]; //辅助空间,用以暂存已经排序的数组元素

  23. void Swap(int &a, int &b)
  24. {
  25.     int tmp = a;
  26.     a = b;
  27.     b = tmp;
  28. }


  29. /* array 待排序数组
  30. * begin 数组开始的下标
  31. *   end 数组最后一个元素的下标
  32. */
  33. void MergeSort(int *array, int begin, int end)
  34. {
  35.     if(end-begin+1 > 2) //当数组元素个数大于2时,需要继续向下划分(递归)
  36.     {
  37.         MergeSort(array, begin, (end+begin)/2);
  38.         MergeSort(array, (end+begin)/2+1, end);

  39.         //合并已排序好的两部分(begin,(end+begin)/2) 和 ((end+bigin)/2+1,end)
  40.         int i = begin, j = (end+begin)/2+1, k=begin;
  41.         while(i<=(begin+end)/2 && j<=end)
  42.         {//比较两个下标i和j所代表的元素,选择相对小的元素放入到辅助空间other数组中,并移动下标到下一位置
  43.             if(array[i] < array[j])
  44.                 other[k++] = array[i++];
  45.             else
  46.                 other[k++] = array[j++];
  47.         }
  48.         while(i <= (begin+end)/2)   //将剩余元素拷贝至other数组
  49.             other[k++] = array[i++];
  50.         while(j <= end)             //将剩余元素拷贝至other数组
  51.             other[k++] = array[j++];
  52.         for(k=begin; k<=end; ++k)   //将排序好的序列拷贝回数组array中
  53.             array[k] = other[k];
  54.     }
  55.     else //当数组元素个数为2或1时,直接排序
  56.         if(array[end] < array[begin])  Swap(array[end], array[begin]);
  57. }


  58. void Output(int *array, int n)
  59. {
  60.     for(int i=0; i<n; ++i)
  61.         cout<<array[i]<<" ";
  62.     cout<<endl;
  63. }


  64. int main()
  65. {
  66.     MergeSort(array, 0, N-1);
  67.     Output(array, N);
  68.     return 0;
  69. }
复制代码
格式良好的代码也可以参见这里。

我明白堆排序的复杂度是O(nlogn),因为对于数组a[n]中的每一个元素都要到那个二叉完全树中去“筛选”一遍,所以 是 n*logn的复杂度,但归并排序的这个O(nlogn)该如何理解呢?
  多谢!!!

作者: glq2000   发布时间: 2010-08-31

算法同你发的另一个帖子:
http://bbs.chinaunix.net/viewthread.php?tid=1773464

作者: daybreakcx   发布时间: 2010-08-31

两者的公式都是一样的,归并是线性的,也就是那个n,然后分治时候是T(n/2),所以公式是一样的
T(n)=2T(n/2)+n

作者: daybreakcx   发布时间: 2010-08-31

热门下载

更多