归并排序

归并排序的时间复杂度任何情况下都是 O(nlogn),看起来非常优秀。(即便是快速排序,最坏情况下,时间复杂度也是 O(n2)。)

但是,归并排序并没有像快排那样,应用广泛,这是为什么呢?因为它有一个致命的“弱点”,那就是归并排序不是原地排序算法。


这是因为归并排序的合并函数,在合并两个有序数组为一个有序数组时,需要借助额外的存储空间。这一点你应该很容易理解。那我现在问你,归并排序的空间复杂度到底是多少呢?是 O(n),还是 O(nlogn),应该如何分析呢?

实际上,递归代码的空间复杂度并不能像时间复杂度那样累加。刚刚我们忘记了最重要的一点,那就是,尽管每次合并操作都需要申请额外的内存空间,但在合并完成之后,临时开辟的内存空间就被释放掉了。在任意时刻,CPU 只会有一个函数在执行,也就只会有一个临时的内存空间在使用。临时内存空间最大也不会超过 n 个数据的大小,所以空间复杂度是 O(n)。

425163
425163
425163
4216
左右2个有序数组开始并成一个新的有序数组
2416
245136
123456

code

//有序数组的合并void merge(int arr[],int m,int n){    int len=n-m+1;    int i=m;    int mid=(m+n)/2;    int j=mid+1;    int *tmparr=malloc(sizeof(int)*len);    int index=0;    while(i<=mid && j<=n){        if(arr[i]<arr[j]){            tmparr[index++]=arr[i++];        } else if(arr[j]<arr[i]){            tmparr[index++]=arr[j++];        }else{            tmparr[index++]=arr[i++];            tmparr[index++]=arr[j++];        }    }    while(i<=mid){        tmparr[index++]=arr[i++];    }    while(j<=n){        tmparr[index++]=arr[j++];    }    int k=0;    for(;k<index;k++){        arr[m+k]=tmparr[k];    }    free(tmparr);}//归并排序void mergeSort(int arr[],int m,int n){    if(m>=n){        return;    }    int mid=(m+n)/2;    mergeSort(arr,m,mid);    mergeSort(arr,mid+1,n);    merge(arr,m,n);}
©著作权归作者所有:来自51CTO博客作者hkui2010的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. 插入排序和归并排序
  2. 3-18(排序的完结)
  3. 3-17(排序)
  4. 2021-03-16:手写代码:单链表归并排序。
  5. BAT iOS算法面试题(汇总)
  6. 114. 二叉树展开为链表
  7. 3-3
  8. 从数组中移除元素,要求时间复杂度为O(N)空间复杂度为O(1)
  9. 数据结构与算法专题——第三题 最长公共子序列

随机推荐

  1. Java 简单解决springmvc获取properties文
  2. JavaScript打印任意奇数行菱形
  3. Java 网络 IO 模型
  4. 解决Eclipse建立Maven项目后无法建立src/
  5. JAVA WEB 实现第三方登录 -- qq篇
  6. 在docker上编译openjdk8
  7. 教您使用java爬虫gecco抓取JD全部商品信
  8. C#/Java 调用WSDL接口及方法
  9. 数据结构:关于重建二叉树的三种思路
  10. 记录一次LinkError排错: