数据结构——排序(空间复杂度、时间复杂度、性能等分析)

目录

(1)插入排序1

①直接插入排序1

②折半排序1

③希尔排序(缩小增量排序)1

(2)交换排序2

①冒泡排序2

②快速排序2

(3)选择排序2

①简单选择排序2

②堆排序2

(4)二路归并排序3

(5)基数排序3

数据结构——排序(空间复杂度、时间复杂度、性能等分析)

(1)插入排序

①直接插入排序

【空间】O(1)

【时间】排序过程中,向有序子表中逐个地插入元素的操作进行了n-1趟

最好O(n),元素已有序,每插入一个元素都只需比较一次而不用移动元素

最坏O(n2),初始为逆序,总比较次数达到最大∑i=2n i,总的移动次数达到最大∑i=2n (i+1)

平均O(n2),初始顺序随机,总的比较次数和移动次数均约为n2/4

【比较次数与初始状态】√

【移动次数与初始状态】√

【一趟排序一个关键字到达最终位置】×,如1,2,3,4,5,0在最后一趟排序前没有任何一个关键字到达最终位置

【稳定性】√ 每次插入元素总是从后向前比较再移动,不会出现相同元素相对位置变化

【适用性】基本有序,数据量不大;顺序存储、链式存储(大部分排序只适用于顺序存储)

②折半排序

【空间】O(1)

【时间】相比于直接插入排序,查找插入位置上花的时间大大减少

最好O(nlog2n),

最坏O(n2),

平均O(n2),

【比较次数与初始状态】×,仅取决于表中元素个数n(二叉排序树高)

【移动次数与初始状态】√

【一趟排序一个关键字到达最终位置】×

【稳定性】√

【适用性】关键字较多时

③希尔排序(缩小增量排序)

将待排序表按选区的“增量”分割成若干个特殊的子表,进行直接插入排序,希尔排序每趟都会使整个序列变得更加基本有序,最后再来一趟直接插入排序效率更高

增量选取

①希尔:⌊n/2⌋,⌊n/4⌋……⌊n/2k⌋……2,1

②帕佩尔诺夫和斯塔舍维奇:2k+1,……65,33,17,9,5,3,1,其中k为大于1的整数,2k+1<n,增量序列末尾的1是额外添加的,此时时间复杂度为O(n1.5)

注:①增量序列最后一定是1②增量序列中的值应尽量没有除1以外的公因子(素数)

【空间】O(1)

【时间】依赖于增量系列

最坏O(n2)

平均O(nlog2n)

n在特定范围内,O(n1.3)

【比较次数与初始状态】

【移动次数与初始状态】

【一趟排序一个关键字到达最终位置】

【稳定性】×,相同关键字可能被划分到不同的子表可能会改变他们的相对次序

【适用性】仅适用于顺序存储

(2)交换排序

①冒泡排序

在一趟排序过程中没有发生关键字交换则冒泡排序结束

【空间】O(1)

【时间】

最好O(n),初始有序,比较n-1次,移动0次

最坏O(n2),初始逆序,需要n-1趟排序,第i趟比较n-i次,每次需要移动元素3次交换元素位置,共比较次数∑i=1n-1 (n-i)=n(n-1)/2,移动次数∑i=1n-1 3(n-i)=3n(n-1)/2

平均O(n2)

【比较次数与初始状态】√

【移动次数与初始状态】√

【一趟排序一个关键字到达最终位置】√

【稳定性】√

【适用性】

②快速排序

划分思想,一趟后划分为左右两部分

【空间】递归需要栈,最好⌈log2(n+1) ⌉次即O(log2n),最坏n-1次即O(n)

【时间】与划分是否对称有关,后者又与具体划分算法有关

最好O(nlog2n),平衡划分

最坏O(n2),初始序列基本有序或逆序,两个区域分别有n-1和0个元素,最大程度上的不对称发生在每一层递归上

平均O(nlog2n),是同级别里最好的

【比较次数与初始状态】√

【移动次数与初始状态】√

【一趟排序一个关键字到达最终位置】√

【稳定性】×

【适用性】初始序列越无序越高效,可根据第i趟是否有i个元素在最终位置,再比较其是否将序列划分为为左右两部分判断是否是快排

(3)选择排序

①简单选择排序

【空间】O(1)

【时间】移动次数很少,不会超过3(n-1),有序时最好0次;比较次数与初始序列无关,始终是n(n-1)/2次,时间复杂度始终为O(n2)

【比较次数与初始状态】× O(n2)

【移动次数与初始状态】√ O(nn2)

【一趟排序一个关键字到达最终位置】√

【稳定性】× 第i趟找到最小元素后和第i个元素交换,可能导致相对位置发生变化,顺序表交换会导致不稳定,链表插入版不会导致不稳定,若无特别说明则是顺序表

【适用性】

②堆排序

小根堆满足L(i)<=L(2i) && L(i)<=L(2i+1),大根堆满足L(i)>=L(2i) && L(i)>=L(2i+1)

建立大根堆,输出堆顶(或者放到最后加入有序序列),将堆底元素送入堆顶,重新调整,重复以上过程直到堆中只剩一个元素

插入结点,按照完全二叉树插入在最底层最右边然后调整;删除结点,与最底层最右边结点交换再删除叶结点

筛选(调整),从无序序列所确定的完全二叉树第一个非叶结点,从右至左,从上至下依次调整。将结点p与其孩子值比较,若孩子大,与最大的孩子交换,p来到下一层重复以上操作直到孩子值都小于p

【空间】O(1)

【时间】O(nlog2n),建堆O(n), 只有n-1次向下调整,每次调整时间复杂度与树高有关为O(log2n)(也是插入一个、删除一个元素的复杂度)

【比较次数与初始状态】

【移动次数与初始状态】

【一趟排序一个关键字到达最终位置】√

【稳定性】× 进行筛选时有可能把后面相同关键字元素调整到前面

【适用性】在所有时间复杂度O(nlog2n)中空间复杂度最小,适合关键字较多的情况,如10000个关键字中选出10个最小

【题】小根堆,最大关键字一定存储在对应完全二叉树的叶子结点中,最后一个非叶子结点存储在⌊n/2⌋,所以最大关键字在⌊n/2⌋ +1~n之间

(4)二路归并排序

K路归并n个元素,趟数m= ⌈logkn ⌉

【空间】O(n)

【时间】O(nlog2n),每一趟O(n),共⌈log2n ⌉趟

【比较次数与初始状态】

【移动次数与初始状态】

【一趟排序一个关键字到达最终位置】×

【稳定性】√

【适用性】

(5)基数排序

借助“分配”和“收集”对单逻辑关键字操作,n个关键字,d为关键字位数,r为关键字基的个数,如930等三位数排序,d=3(3位),r=10(0~9)

【空间】O®

【时间】一趟分配O(n),一趟收集O®,一共需要d趟分配和收集,时间复杂度O(d(n+r)),与初始状态无关

【比较次数与初始状态】

【移动次数与初始状态】

【一趟排序一个关键字到达最终位置】×

【稳定性】√

【适用性】关键字很多,但构成关键字的元素取值范围很小(r很小)。如果关键字取值范围也很大,如26个字母并且序列中大多数关键字关键字都不同,可以考虑使用“最高为优先”,根据最高位排成若干子序列,再对子序列进行直接插入排序

相关推荐