排序(3)
来源:互联网 发布:maven 书籍 推荐 知乎 编辑:程序博客网 时间:2024/06/16 16:22
level3,下面介绍几种稳定的排序方式,主要是两种,一个是堆排序(也叫做锦标赛排序),第二个就是我们经常用的二路归并排序,第三个就是多路归并排序(JDK)
当时在学校的时候觉得,快速排序真的是一个很好的想法,后来又看到了令人巧妙到让人不理解的一些思想。
下面说下堆排序,介绍原理,
其别名很形象,锦标赛,也就是一个二叉树状比赛,赢了就出去,下面继续打。
这个打的过程称做堆重构,赢的数字就是极值,这种比较和交换,绝对是超稳定的,因为只有两个点。
如下数字:64,96,19,52,85,71,64,48,1,78
堆排序也是分治的一种,堆重构也是小方法体之一,巧妙在它对于一个数组的理解,把一个数组当作一个树来比较了。。
64
96 19
52 85 71 64
48 1 78
这里假设四个变量 block 数组,start,end,哨兵p,start,end为数组位置,不是地址索引,即start=index+1,在java和c里面是如此的。
p开始初始化为数组第一个,block[start-1], 即是root
它是怎么做的呢,首先,从i=start*2 开始,这里就是96,然后和19比较,如果96>10,那么和block[start-1]互换一下,保证
block[start-1]是堆的胜出点,
然后再判断i,这个是否到了尾部,如果不是,那么当前i=i*2,刚才的i是2,所以现在的i=4了,52和84比较,小,pass,
前进直到找到最大,85,block[i-1],下面是同理,
最后返回这个堆极值点。
堆重构:private static void HeapAdjust(int arr[], int start, int end) { int temp = arr[start - 1]; for (int i = start<<1; i <= end; i = i<<1) { if (i < end && (arr[i - 1] < arr[i])) i++; if (temp >= arr[i - 1]) break; arr[start - 1] = arr[i - 1]; start = i; } arr[start - 1] = temp; }
好了。。。
下面定义大方法体,
相当简单,将构造的堆的胜者一个一个放在数组后面。。
代码如下: public static void HeapSort(int arr[]) { int temp; int len = arr.length; for (int i = len >>1; i > 0; i--) HeapAdjust(arr, i, len); for (int j = len; j > 1; j--) { temp = arr[0]; arr[0] = arr[j - 1]; arr[j - 1] = temp; HeapAdjust(arr, 1, j - 1); } }
测试一下:
100*10000 ,execute time:250
1000*10000 ,execute time:2735
发现在运行的时候好像有点慢,其实这是因为构建堆的时候是比较耗资源的,
为了突出其稳定性,再执行几次。
1000*10000 ,execute time:2750
1000*10000 , execute time:2859
1000*10000, execute time:2687
execute time:2735
首先快速是在数量级中等时是比较适合的,1000W级别并不很适合。
然后快速在100W级别的时间,看看其稳定性:
1. execute time:8141
2. execute time:8360
3.execute time:8469
4.execute time:8250
首先,这两个是不在一个数量级,但是1000W能精确到200ms左右,而quickSort 100W是在300ms浮动,
还有稳定会带一定的好处就是,减少交换的次数,这点在这两者之间体现的相当明显。
- 排序(3)冒泡排序
- 排序(3)--快速排序
- 排序(3)---归并排序
- 排序3:插入排序(2路插入排序)
- 经典排序算法3(选择排序)
- C++排序之选择排序(3)
- 排序算法小结(3)交换排序
- 排序算法(3):冒泡排序
- 排序(3)——插入排序
- 排序算法(3):归并排序
- java排序(3):交换类排序
- 排序算法(3)-简单选择排序
- 排序算法(3)--归并排序
- 内部排序算法3(选择排序)
- 排序(3)直接插入排序
- 算法排序(3):选择排序
- [排序算法] 插入排序(3种)
- 算法、排序(3)
- 我理解的逻辑地址、线性地址、物理地址和虚拟地址
- 大心脏
- C++学习代码--pointer
- 排序(2)
- 使用函数指针来代替switch语句
- 排序(3)
- 十个糟糕的程序员的行为
- C++学习代码--file
- Android 初始化语言(Android init Language翻译)
- 外企九年-我最终选择放弃
- 在Vim中编辑Qt4
- 浏览器缓存知识收藏
- 经济衰退时期发屈CRM潜力
- 怎么成为优秀的软件模型设计者?