快速排序的层次改进
来源:互联网 发布:mac cad中文版 编辑:程序博客网 时间:2024/06/06 01:43
1 快速排序划分序列的方法
(1) 第一种
第一种方法,先扫描右边的元素,一旦遇到比t大的元素就将此元素移到最左边,然后再从左边开始,一旦遇到比t大的元素就将此元素放到右边,再从右边…….直到左右交错。最后将t放到划分位置处。
while( l < h){//Check elements in back
while(h > l && a[h] >= t){
--h;
}
//The back element which less than the key value
a[l] = a[h];
while(l < h && a[l] <= t){
++l;
}
a[h] = a[l];
}
//l = h
a[l] = temp;
(2) 第二种Lomuto划分方案
从左到右扫描,遇见比t小的就和最左大的元素交换,用m作为比t小的最右元素的下标,最后再将t和划分位置(m)元素交换。m = l -1
for i = [l, h]
if a[i] < t // a[i] > t若从大到小排序
swap(++m, i)
swap(m, l) //a[l]被选作划分序列的元素即t
swap()函数用于交换数组中的两个元素。程序中能访问到的a[m]始终是左边最后一个小于于t的数组元素,a[m+1](除a[u+1])是大于t的第一个数组元素。
(3)第三种 Bob Sedgewick划分方案
m = h + 1
for i = [u, l]
if a[i] >= t
swap(--m, i)
程序中能访问到的a[m]是大于等于t最左边的一个元素,a[m-1]是小于t的一个元素。故而循环完毕后,不再需要swap语句。这样就比Lomuto少一个语句。
m = i = h + 1
do
while a[--i] < t
NULL;
swap(--m, i)
while i != l
程序中能访问到的a[m]为大于t的最左一个元素。
2 特殊输入时改善快速排序
当待排序列全为相等的元素(某部分为全为相等的序列)和待排序列已经有序时快排的时间复杂度为O(n^2)(当选取第一个元素作为t时)。当序列达到1M时,此时快速排序的时间将会达几个小时,而O(nlogn)处理1M数据是秒级别的。(1) 排相等元素
此时划分序列的代码需要更改如下:loop
do i++ while i < h && a[i] < t
do j-- while a[j] > t
if i > j break
swap(i, j)
swap(i, j) //划分完成“当前序列”的所有元素相同时,i, j每次都分别增加1和减少1,这样可保证这个序列基本被二分,故而递归处理深度为logn,而函数的复杂度为n,故而这样改写程序后,即便在所有序列元素都相同的情况下,快速排序的时间复杂度都能够有O(nlogn)的保证。在各元素不相同时,swap(i, j)完成左右两边不满足和t关系的元素之间的交换。
(2) 排有序元素
因为当待排序列已经有序时,每次都将序列划分为1 和n-1的序列,如此就需要n此划分。结合函数本身的O(n),造就快排的时间复杂度为O(n^2)。
3 总结
这只是快排的一个例子,它经历了两个层次:
- 算法本身的改进。
- 改进算法面对的特殊情况。
Small Box Note Over。
0 0
- 快速排序的层次改进
- 快速排序的改进
- 快速排序的改进
- 快速排序的改进
- 改进的快速排序
- 快速排序的改进-随机快速排序
- 快速排序算法的改进
- 改进版本的快速排序
- 快速排序的改进算法
- 改进的快速排序算法
- 快速排序的改进方法
- 快速排序的改进方法
- 快速排序的改进方法
- 快速排序:改进后的冒泡排序
- 快速排序的几种改进
- 快速排序 改进快排的方法
- 快速排序 改进快排的方法
- 快速排序 改进快排的方法
- 学习bash shell 3
- UVa 10014 简单的计算
- UITableView的基本使用二(性能优化)
- 基础加强____【Java类加载器 & "委托机制"】
- 小P的故事——神奇的Dota
- 快速排序的层次改进
- 高手速成android开源项目【developer篇】
- max函数比较字符串类型
- 哈希表学习实例
- innotop 下载安装步骤
- 黑马程序员-JAVA高级(IO输入与输出)PART3
- grep
- BFS算法
- 深层解读:唯品会、乐蜂、聚美的那些事