算法导论(二)——查找、排序和顺序统计
来源:互联网 发布:淘宝二手机可靠吗 编辑:程序博客网 时间:2024/05/08 09:32
第六章 堆排序
1. 原地排序算法: 只有常数个数的元素会被移动到集合之外
2. 堆作为一种数据结构,不光用在堆排序,还用在优先队列中。堆在 lgn的时间内可生成N的优先队列
堆:完全二叉树;节点大于子节点
3. 好的快排要优于堆排
堆排序实现
保持堆的性质:maxHeapify(A, i)
if A[i]<A[2i] or A[i]<A[2i+1]
swap A[i]和 max(A[2i], A[2i+1]) //将 A[i]及其left和right子节点中较大的作为父节点
创建最大堆: buildMaxHeap(A)
heap_size(A)=length(A)
for i heap_size(A)/2 to 1 // heap_size (A)/2 是最底层偏右的父节点
maxHeapify(A,i)
堆排序:
1. 建立最大堆
2. 将堆的第一个和最后一个交换
3. 堆的size -1
buildMaxHeap(A)
for i n-1 to 1 {
swap(A[0] , A[i])
heap_size(A)=heap_size(A)-1
maxHeapify(A(0))
}
优先队列
堆可以在lgn的时间内,支持任意时间内的优先队列操作
支持以下操作:
insert(H,a): a插入堆,并保持堆的性质
将 a插入H的末尾
if( a> parent(a) ) {
交换a 和其父节点
}// 一直调整到根节点
maxium(H) :从H中选择最大值
return H[0];
extract-max(H): 从H中取出最大值
swap H中第一个和最后一个元素
heap_size(A)--;
maxHeapify(H[0])
return H 最后一个元素
increase-key(H, i,k) 增加H中第i个元素的优先级到k
H[i].key+=k;
if( H[i]> parent(H[i]) ) {
交换H[i] 和其父节点
}// 一直调整到根节点
应用:
在分时计算机上进行优先调度
第七章 快速排序
1. 快排平均时间 nlgn,最坏时间 n的平方。由于常数因子小,是内部排序的默认选择.
2. 快排在数组基本有序时出现最坏情况,所以需要随机化技术(从数组中随机选择一个元素和最末端的元素交换)
快速排序的实现
使用分治法的策略:
分解:使用 Partition(A , start ,end)取得划分小标q,使得 A[i]<A[q]<A[j] 当 i<q<j时
解决:对各部分递归调用快速排序
合并:不需要
其中 partition很关键,尽量划分到中间,如果划分成 n-2 和1就惨了,退化成 n的平方了
partition(A, start ,end )
swap A[ start和end之间的随机数], A[end]
x=A[end] //取end元素作为划分元素
i=start-1 // i标示目前为止小于 x的元素最大下标
for j start to end-1 // j标示循环变量
{
if(A[j]<x) { // i加1,并将 A[i] 与当前循环元素交换
i++;
A[i]<-->A[j];
}
}
A[i+1]<-->A[end] //循环完后,交换i下一个和最后元素
return i+1;
第八章 线性排序
1. 任何以比较为基础的排序,时间下限是 nlgn
2. 线性时间运行的排序:基数排序,桶排序,计数排序。这些排序都建立在一些限定条件的基础上
计数排序
a) 稳定的排序。
b) 用于小规模数据的排序
c) 缺点在于:
i. 需要很多额外的空间(当前类型的值的范围,排序结果)
ii. 只能对离散的类型有效比如int(double就不行了)
iii. 基于假设:输入是小范围内[0,k]的整数构成的。
iv. 不是原地排序
实现:
// C 存放值的范围,A为输入,B为输出
1. 对A遍历: C[ A[i] ] 为A[i]出现的个数
2. 对C遍历: C[ j ] = C[j -1]+C[j] C[ j ]为 j开始的下标
3. 对A逆序遍历从n到1(稳定性)
B[ C[ A[i] ] ]=A[i] //A在B中对应位置
C[ A[i] ] --; //C中对应元素值减一
基数排序
用于对有多个关键字的记录进行排序,常使用计数排序作为单个关键字的排序
a) 单个关键字调用的子排序算法是稳定的。
b) 基数排序与直觉相反:它是按照从底位到高位的顺序排序的
c) 常数因子比较大
实现:
先从最低为,排到最高位
桶排序
期望运行时间是线性,最坏是nlgn
假设: 数据均匀分布,且在 [0,1]
总结: 基本没什么用,限定了输入空间,且要求均匀分布,最坏在 nlgn
外部排序(k路归并排序)
按内存大小利用内部排序构造有序子序列,对子序列进行归并
排序的比较
名称
时间复杂度
稳定
空间
堆排序
Nlgn
不
原地排序
快速排序
Nlgn,最差O(n^2)
不
原地排序
归并排序
Nlgn
稳定
O(n)
基数排序
O(d(n+rd))
稳定
有条件
选择:
记录数n,单条记录大小,关键字结构及初始状态,时间和辅助空间复杂度
n比较小的时候,适合插入排序和选择排序
基本有序的时候,适合直接插入排序和冒泡排序
n很大但是关键字的位数较少时,适合链式基数排序
n很大的时候,适合快速排序堆排序归并排序,要排序稳定使用归并
查找
顺序查找:最简单的查找
二分查找:如果元素已经有序
静态查找表(不等概率下的查找):构造次优二叉树(递归求权值,最优权值和最小为根)
索引顺序表:查找内容分块有序,i+1块的大于i块。 先在索引中二分查找,再在手中查找
动态查找表:二叉查找树,找不到就插入
哈希表: 基本为O(1)
第九章 中位数和顺序统计学
1. 同时找最大最小值算法 3*n/2
遍历步长为2,每对元素先比较,再让小的和min比较,大的和 max比较
for(i=0 ;i<n;i=i+2) {
if( a[i] < a[i+1]) {
if( a[i] < min) {
}
if (a[i+1] >max) {
}
}
}
2. 在 O(n)时间内求第 i小的元素(或中位数)
使用快速排序中的 partition函数
1. 运行 partition得到划分下标 k
2. 如果 i<k,则在 start, k 间质性 partition;否则在 k end间执行;相等则直接返回
该算法可以在期望时间为O(n)
最坏情况的核心在于:要保证对数组的划分是一个好的划分。于是方法使用了一个很奇怪的取主元的方法,虽然看起来很奇怪,但是该方法被这样的提出就肯定有它的理论基础的。
- 算法导论(二)——查找、排序和顺序统计
- 算法导论学习(二)——排序和顺序统计量
- 排序和顺序统计量(算法导论)
- MIT:算法导论——4.1.排序和顺序统计量_堆排序
- [学习《算法导论》]第二部分 排序和顺序统计量
- 排序和顺序统计学(算法导论)
- 算法导论之中位数和顺序统计量(1)
- 算法导论之中位数和顺序统计量(3)
- 算法导论读书笔记(9)中位数和顺序统计量
- 算法导论第十四章利用红黑树查找顺序统计量
- 算法导论(二)——排序算法整理
- 算法导论—中位数与顺序统计量
- 算法导论(4) 顺序统计量
- 算法导论之排序和顺序统计学
- 【算法导论】中位数和顺序统计量之选择算法
- 中位数和顺序统计(线性时间)算法导论9.2
- [算法导论]第九章《中位数和顺序统计量》
- 算法导论第九章-中位数和顺序统计量
- 锤子ROM那些欠缺考虑的微创新们
- 仿windows8 开始菜单 实现HubTileBase 以及仿鲜果联播实现 PulsingTile(脉冲磁贴)
- file操作
- hdu 4021 15数码
- Ubuntu12.04搭建hadoop集群版环境
- 算法导论(二)——查找、排序和顺序统计
- Visual Studio 2010——安装过程记录
- 打鼾的治疗方法
- 算法导论(三)——数据结构
- 从客户端中检测到有潜在危险的 Request.Form 值错误解决方法
- 让input不可选的几种方法
- ubuntu升级git
- 分页取出下标小方法
- 算法导论(四)——算法和分析技术