概述
文章目录
- 堆排序的过程
- 建立初始堆(大根堆)
- 交换堆顶元素与堆底元素,并重新调整大根堆
- 时间复杂度
- 空间复杂度
说明:阅读本文章的前提是对堆排序过程有大致了解,此处重点讲解算法的复杂度
堆排序的过程
每次交换堆顶元素和堆底元素之后,待排序元素个数就少一个
初始状态
建立初始堆(大根堆)
依次从后往前逐渐调整,只考虑非叶子节点(分支节点),第一个调整的元素为“最后一个非叶子节点”,即【233】
- 考虑【233】
其左孩子为【888】,无右孩子。【888】比【233】大,交换【233】与【888】。结果如下:
交换后,【233】无孩子节点,无需继续考虑【233】
- 考虑【666】
其左右孩子中,【985】比【688】大。且【985】比【666】也大,交换【666】与【985】。结果如下:
交换后,【666】无孩子节点,无需继续考虑【666】
- 考虑【211】
其左右孩子中,【985】比【888】大。且【985】比【211】也大,交换【211】与【985】。结果如下:
交换后,【211】有孩子节点。其左右孩子中,【688】比【666】大。且【688】比【211】也大,交换【211】与【688】。结果如下:
至此,已建立大根堆
交换堆顶元素与堆底元素,并重新调整大根堆
- 将堆顶元素【985】与堆底元素【233】交换。结果如下:
此时待排序元素(前5个)已不是大根堆,需要重新调整为大根堆
考虑堆顶元素【233】
其右孩子【888】比左孩子【688】更大。且【888】比【233】也大。交换【233】与【888】。结果如下:
交换后,【233】无孩子节点(985为排好序的元素),无需继续考虑【233】
- 将堆顶元素【888】与堆底元素【666】交换。结果如下:
此时待排序元素(前4个)已不是大根堆,需要重新调整为大根堆
考虑堆顶元素【666】
其左孩子【688】比左孩子【233】更大。且【688】比【666】也大。交换【666】与【688】。结果如下:
交换后,【666】有左孩子节点【211】(888为排好序的元素),但【211】比【666】小,不再进行调整
- 将堆顶元素【688】与堆底元素【211】交换。结果如下:
此时待排序元素(前3个)已不是大根堆,需要重新调整为大根堆
考虑堆顶元素【211】
其左孩子【666】比左孩子【233】更大。且【666】比【211】也大。交换【211】与【666】。结果如下:
交换后,【211】无孩子节点(688、888为排好序的元素),无需继续考虑【211】
- 将堆顶元素【666】与堆底元素【233】交换。结果如下:
此时待排序元素(前2个)仍是大根堆,无需调整
- 将堆顶元素【233】与堆底元素【211】交换。结果如下:
此时待排序元素(前1个)仍是大根堆,无需调整。
排序完成(升序),211<233<666<688<888<985
时间复杂度
建堆的时间复杂度
在调整堆时,每交换一次节点,最多比较关键字2次
- 比较1次:目标节点只有左孩子,无右孩子,将目标节点与其左孩子比较1下
- 比较2次:目标节点左右孩子均有,首先左右孩子先比较1下,然后大者再与目标节点比较1下
若目标节点在 x x x层,树高为 h h h,则调整时,目标节点最多交换 ( h − x ) (h-x) (h−x)次,每次最多比较2次关键字,故 x x x层节点的关键字对比次数不超过 2 × ( h − x ) 2times(h-x) 2×(h−x)次
假设一颗完全二叉树,树高为h,最后一层节点无需进行调整
第1层共有1个节点,关键字对比次数最多为 1 × 2 × ( h − 1 ) 1times2times(h-1) 1×2×(h−1)次
第2层共有2个节点,关键字对比次数最多为 2 × 2 × ( h − 2 ) 2times2times(h-2) 2×2×(h−2)次
第h-1层共有2h-2个节点,关键字对比次数最多 2 h − 2 × 2 × 1 2^{h-2}times2times1 2h−2×2×1次
将整颗树调整为大根堆,关键字对比次数最多 1 × 2 × ( h − 1 ) + 2 × 2 × ( h − 2 ) + . . . + 2 h − 2 × 2 × 1 1times2times(h-1)+2times2times(h-2)+...+2^{h-2}times2times1 1×2×(h−1)+2×2×(h−2)+...+2h−2×2×1次
处理上式为: ∑ i = 1 h − 1 2 i − 1 × 2 × ( h − i ) = ∑ i = 1 h − 1 2 i × ( h − i ) sum_{i=1}^{h-1}2^{i-1}times2times(h-i)=sum_{i=1}^{h-1}2^{i}times(h-i) ∑i=1h−12i−1×2×(h−i)=∑i=1h−12i×(h−i)
由于n个节点的完全二叉树的高 h = log 2 n + 1 h=log_2 n+1 h=log2n+1(向下取整)
令 j = h − i , 则 i = h − j 。 令j=h-i,则i=h-j。 令j=h−i,则i=h−j。原式 = ∑ j = h − 1 1 2 h − j × j = ∑ j = log 2 n 1 2 log 2 n + 1 − j × j = ∑ j = log 2 n 1 n × 2 × 2 − j × j = 2 n × ∑ j = log 2 n 1 2 − j × j =sum_{j=h-1}^{1} 2^{h-j} times j=sum_{j=log_2 n}^{1} 2^{log_2 n +1-j} times j=sum_{j=log_2 n}^{1} ntimes 2 times 2^{-j} times j=2ntimes sum_{j=log_2 n}^{1} 2^{-j} times j =∑j=h−112h−j×j=∑j=log2n12log2n+1−j×j=∑j=log2n1n×2×2−j×j=2n×∑j=log2n12−j×j
考虑 S n = ∑ j = h 1 2 − j × j = ∑ j = 1 h 2 − j × j = 1 × 1 2 + 2 × 1 4 + 3 × 1 8 + . . . + h × 1 2 h S_n=sum_{j=h}^{1} 2^{-j} times j=sum_{j=1}^{h} 2^{-j} times j=1timesfrac{1}{2}+2timesfrac{1}{4}+3timesfrac{1}{8}+...+htimesfrac{1}{2^h} Sn=∑j=h12−j×j=∑j=1h2−j×j=1×21+2×41+3×81+...+h×2h1 ①
将 ① × 1 2 ①timesfrac{1}{2} ①×21 得 1 2 S n = 1 × 1 4 + 2 × 1 8 + . . . + ( h − 1 ) × 1 2 h + h × 1 2 h + 1 frac{1}{2}S_n=1timesfrac{1}{4}+2timesfrac{1}{8}+...+(h-1)timesfrac{1}{2^h}+htimesfrac{1}{2^{h+1}} 21Sn=1×41+2×81+...+(h−1)×2h1+h×2h+11 ②
使用错误相减法②-①得: 1 2 S n = 1 2 + 1 4 + 1 8 + . . . + 1 2 h − h × 1 2 h + 1 = 1 2 ( 1 − 1 2 n ) 1 − 1 2 − h × 1 2 h + 1 = 1 − 1 2 n − h 2 h + 1 frac{1}{2}S_n=frac{1}{2}+frac{1}{4}+frac{1}{8}+...+frac{1}{2^{h}}-htimesfrac{1}{2^{h+1}}=frac{frac{1}{2}(1-frac{1}{2^n})}{1-frac{1}{2}}-htimesfrac{1}{2^{h+1}}=1-frac{1}{2^n}-frac{h}{2^{h+1}} 21Sn=21+41+81+...+2h1−h×2h+11=1−2121(1−2n1)−h×2h+11=1−2n1−2h+1h ③
将 ③ × 2 ③times2 ③×2得: S n = 2 − 1 2 h − 1 − h 2 h S_n=2-frac{1}{2^{h-1}}-frac{h}{2^h} Sn=2−2h−11−2hh④
很明显④式小于2即 S n < 2 , 所 以 2 n × ∑ j = log 2 n 1 2 − j × j < 4 n S_n< 2,所以2ntimes sum_{j=log_2 n}^{1} 2^{-j} times j<4n Sn<2,所以2n×∑j=log2n12−j×j<4n
建堆的时间复杂度为O(n)
交换堆顶底元素后重建堆的时间复杂度
每次将堆顶元素与堆底元素进行交换后,需要将剩余待排序元素重新建堆。此时处理的是堆顶元素,即根节点。根节点位于第一层,关键字最多比较次数为 2 × ( h − 1 ) 2times(h-1) 2×(h−1)次。
上述过程共需进行n-1次(n为节点个数),故重建堆的总的关键字最多比较次数为 2 × ( h − 1 ) × ( n − 1 ) = 2 log 2 n ( n − 1 ) 2times(h-1)times(n-1)=2log_2 n (n-1) 2×(h−1)×(n−1)=2log2n(n−1)
重建堆的时间复杂度为O(nlogn)
堆排序的时间复杂度为O(nlogn)+O(n)=O(nlogn)
空间复杂度
整个排序过程,包括初建堆、交换顶底元素、重建堆,未用到其他多余的空间,主要进行比较与交换工作,所以空间复杂度是O(1)
最后
以上就是羞涩乌龟为你收集整理的【数据结构】堆排序的算法复杂度分析堆排序的过程时间复杂度空间复杂度的全部内容,希望文章能够帮你解决【数据结构】堆排序的算法复杂度分析堆排序的过程时间复杂度空间复杂度所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复