合并排序,合为重
来源:互联网 发布:数控编程仿真软件 编辑:程序博客网 时间:2024/05/16 19:35
陆小凤原创
小白:陆大侠,从快排到合排,算法思想有变化吗?
陆小凤:在设计思想上,它们是一样的,都是“分而治之”的思想。
小白:“分而治之”,就是我老板常说的话啦:“没有什么是搞不定!只要你把它分解得足够小,就能解决!”
陆小凤:“除了解决小的问题,还要把结果组合起来。““
合并排序的设计思想,从大的层面来讲是“分而治之”的体现,从实现的角度来说,分与合是重点。
本文介绍合并排序的设计与实现。
合并排序,先是要分(一分为二),分到只有一个元素为止。然后是合,先是两个元素合在一起,再是多个元素合在一起。
参考以下这个演示图,可以更好地理解合排的设计与实现:
上面这个图,注意不同颜色框的变化(分与合的变化)。
再参考另一个演示图:
小白:我依稀看到了实现的办法,只要分成两部分,再递归调用自己来排好序,再合并在一起即可。陆大侠,你之前讲的递归又发挥作用了!
陆小凤:不要把递归实现跟设计思想混在一起。设计上,是一直分下去,再合起来。但实现时,不一定要用递归,比如可以把分出来的部分,用数组保存起来,再对这个数组内的部分作细分…,用迭代也能实现。只不过,
递归是很自然的实现选择,而且简洁。但是,你要有“空手套白狼”的勇气才敢于用上递归实现。小白:就是先假设我的函数已经实现排序了,再在函数里面调用自己,对某部分作排序了。东风吹战鼓擂,这个世界谁怕谁?
合并排序的分(O(logn))与合(O(n)),整体的时间复杂度是O(nlogn),而且是稳定排序。
小白:那岂不是比快排还要快,因为快排有可能变为n的平方?
陆小凤:不是。快排有可能变成n的平方,这种极端的情况是低概率的,而且,可以先打乱再来快排,从而避免
去到O(n^2),或者去到极低概率。在都为O(nlogn)时,快排的系数比合排更小,所以速度更快。另外,合排需要额外的空间来保存合并的结果,而快排不需要。小白:这个…,看来quicksort是实至名归!
在工程中,快排的效果比合排更优,但注意高层次的设计思想是一样的。
以下是合并排序的一个实现演示。
#include <stdio.h>#include <stdlib.h>void merge(int* arr, int f, int m, int l, int* tmparr) { int i=f, j=m+1; int k=0; while (i<=m && j<=l) { if (arr[i] > arr[j]) { tmparr[k++]=arr[j++]; } else { tmparr[k++]=arr[i++]; } } while (i<=m) { tmparr[k++]=arr[i++]; } while (j<=l) { tmparr[k++]=arr[j++]; } for (i=0; i<k; i++) { arr[f++]=tmparr[i]; }}void _sort_merge(int* arr, int f, int l, int* tmparr) { if (f < l) { int m=(f+l)>>1; _sort_merge(arr, f, m, tmparr); _sort_merge(arr, m+1, l, tmparr); merge(arr, f, m, l, tmparr); }}void sort_merge(int* arr, int size) { int* tmparr=(int*)malloc(sizeof(int) * size); _sort_merge(arr, 0, size-1, tmparr); free(tmparr);}int main(int argc, char *argv[]){ int arr[] = {4, 2, 5, 1, 6, 6, 8, 9, 8, 3}; int size=sizeof arr/sizeof *arr; for (int i = 0; i < size; i ++) { printf("%d, ", arr[i]); } sort_merge(arr, size); printf("\nafter_sort:\n"); for (int i = 0; i < size; i ++) { printf("%d, ", arr[i]); } printf("\n"); return 0;}
- 合并排序,合为重
- Spring中集合合并
- ridView 合并单元格 合并行
- Oracle 合并行,合并列
- 合并排序
- 合并排序
- 合并排序
- 合并排序
- 合并排序
- 合并排序
- 合并排序
- 合并排序
- 合并排序
- 合并排序
- 合并排序
- 合并排序
- 合并排序
- 合并排序
- CSDN 第一篇博文
- linux下启动svn实例
- Spring Cloud (19) | Eureka Server 高可用服务注册中心
- Django实现CAS+OAuth2
- demon14.5-14.6
- 合并排序,合为重
- React中setState回调
- C语言总结
- 对数函数
- Unity3D 鼠标拖动和旋转物体以及鼠标拖动图片
- HTML中      等6种空白空格实体的区别
- 【解决】:不能删除旧版本的Apple Software Update
- HTTP和FTP的区别的一些理论知识
- Cocos2d-x内存管理之autorelease,addChild和removeFromParent