学堂在线数据结构下_第14章_排序sort
20220604
-
【1】快速排序Quicksort:
本质——快速确定轴点Pivot,将全部元素逐一转换为轴点。
Quicksort与Mergesort都采用递归分治策略;
mergesort的计算量是合并两子序列;
quicksort的计算量是恰好把序列划分为左小右大的两子序列。
轴点的左侧小于轴点,轴点的右侧大于轴点。
轴点的秩 == 该轴点在排序后的秩。
轴点就是在排序前就已就位的元素。
把待排序序列的首字符预设为轴点值,S形交替遍历,最终确定该轴点值在序列中的轴点位置(秩)。
空间复杂度 = O(n+1);
最好情况的时间复杂度 = O(nlogn),此时,预设的轴点的秩约为n/2,运气好;
最坏情况的时间复杂度 = O(n^2),此时,待排序序列事先已有序。
平均时间复杂度 = O(nlogn)。
---
【2】选取问题selection:
中位数median选择问题 是 k-selection问题中 难度最大的特例。
众数majority-selection问题(可用减而治之):众数若存在,则亦必为中位数。
频繁数mode-selection问题:众数若存在,则亦必为频繁数。众数是频繁数的特例。
---
20220605
【2.1】k-selection选取问题的通用算法:
蛮力算法——先排序,再选取第k位元素。O(nlogn)耗时大。
k-selection问题是二叉堆getMax()的推广;二叉堆getMax()是k-selection问题的特例。
(1)先尝试小顶堆(二叉堆的堆顶是最小元),进行k次delMin()操作,堆顶即全局秩为kd 元素。建堆Heapifiation可用Floyd算法,时间复杂度O(n);delMin()花费时间O(k*logn),所以若k同阶于n,则与蛮力算法耗时相当。
(2)再尝试大顶堆,时间复杂度O(k)+O(2*(n-k)logk),若k接近n/2,则退化为蛮力算法。
(3)再尝试大顶堆+小顶堆,最坏情况依旧很耗时。
(4)quickSelect算法:减而治之,借用快速排序的patition算法。仿照快速排序算法,预先选定一个轴点pivot(秩为i),比较k与i的大小关系。最坏情况的时间复杂度 = O(n^2)。
(5)linearSelect算法:改进版quickSelect算法。最坏情况的时间复杂度 = O(n)。递归base Q;n/Q个子序列;每个子序列进行insertsort,找出中位数m;找出n/Q个m中的中位数M;依据M,把全序列划分为L、E、G三个子序列;缩小问题规模,递归执行上述步骤。时间复杂度 T(n)=O(n)+T(n/Q)+T(3n/4)。
---
【3】Shellsort希尔排序:1959
迭代递减增量排序法(矩阵列数递减)。
把待排序序列 视为 矩阵。矩阵的列数为w_k,从第1列至第w_k列 逐列各自排序 称为 (w_k)-sorting。(w_k)-sorting后的(每列各自有序的)矩阵为(w_k)-ordered状态。然后,Shellsort将 (w_k)-ordered矩阵 重组为一个更高更瘦的(行数更多,列数 = (w_k-1) < (w_k))新矩阵,再对新矩阵进行下一轮 (w_k-1)-sorting……循环迭代上述步骤,直至1-sorting。
全局排序过程中,矩阵行数越来越多、列数越来越少(即矩阵从矮胖到瘦高),最终迭代为1-sorting(待排序序列 已全排序)。
步长序列step sequence={1, w_2, ..., w_k-1, w_k}。
不同的step sequence 对应不同效率的Shellsort。
Shellsort是CD机,不同的step sequence是不同的CD唱片。
-
Shellsort:Call-by-rank。
二维矩阵只存在于逻辑中;物理上;待排序序列自始至终都是一维向量。
-
每轮w-sorting过程中的各列内部排序,适用 输入敏感型算法(比如,插入排序insertionsort 对输入序列的有序程度敏感)。因为,随着w递减,各列有序程度越来越好(逆序对 越来越少),若各列用insertionsort算法 可减少I/O操作次数、减少时间复杂度。
-
定理K(见《计算机程序设计艺术》第三卷,英文版90页,中文版72页):
k-ordered序列经过h-sorting之后,依旧保持k-ordered。
【固定间隔的有序性,在Shellsort过程中,将被不断积累下来,直至实现 间隔为1的有序性(相邻元素均有序,即全排序)。】
-
某一序列若既是k-ordered、又是h-ordered,可记作(k,h)-ordered,则必为(mk+nh)-ordered。mk+nh是k与h的线性组合。
-
数论结果:两素数(k、h)的线性组合mk+nh 无法表示的最大自然数 是 (k-1)(h-1)-1.
【无法表示为mk+nh 的自然数 只可能存在于区间[0,(k-1)(h-1)-1]内。】
-
若把【素数列】定为step sequence,随着Shellsort不断迭代,区间[1, (k-1)(h-1)-1]也在不断缩小,等效于 逆序对总数不断减少,所以适合使用insertionsort(因为逆序数越少,insertionsort效率越高)。
---------------------