IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 【数据结构】堆排序的算法复杂度分析 -> 正文阅读

[数据结构与算法]【数据结构】堆排序的算法复杂度分析

说明:阅读本文章的前提是对堆排序过程有大致了解,此处重点讲解算法的复杂度

堆排序的过程

Created with Rapha?l 2.2.0 开始 建立初始堆 待排序元素个数大于1? 交换堆顶元素和堆底元素 将剩余待排序元素重新建立堆 结束 yes no

每次交换堆顶元素和堆底元素之后,待排序元素个数就少一个


初始状态
初始状态

建立初始堆(大根堆)

依次从后往前逐渐调整,只考虑非叶子节点(分支节点),第一个调整的元素为“最后一个非叶子节点”,即【233】

  1. 考虑【233】

其左孩子为【888】,无右孩子。【888】比【233】大,交换【233】与【888】。结果如下:
在这里插入图片描述
交换后,【233】无孩子节点,无需继续考虑【233】

  1. 考虑【666】

其左右孩子中,【985】比【688】大。且【985】比【666】也大,交换【666】与【985】。结果如下:
在这里插入图片描述
交换后,【666】无孩子节点,无需继续考虑【666】

  1. 考虑【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 ) 2\times(h-x) 2×(h?x)

假设一颗完全二叉树,树高为h,最后一层节点无需进行调整
第1层共有1个节点,关键字对比次数最多为 1 × 2 × ( h ? 1 ) 1\times2\times(h-1) 1×2×(h?1)
第2层共有2个节点,关键字对比次数最多为 2 × 2 × ( h ? 2 ) 2\times2\times(h-2) 2×2×(h?2)
第h-1层共有2h-2个节点,关键字对比次数最多 2 h ? 2 × 2 × 1 2^{h-2}\times2\times1 2h?2×2×1
将整颗树调整为大根堆,关键字对比次数最多 1 × 2 × ( h ? 1 ) + 2 × 2 × ( h ? 2 ) + . . . + 2 h ? 2 × 2 × 1 1\times2\times(h-1)+2\times2\times(h-2)+...+2^{h-2}\times2\times1 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}\times2\times(h-i)=\sum_{i=1}^{h-1}2^{i}\times(h-i) i=1h?1?2i?1×2×(h?i)=i=1h?1?2i×(h?i)
由于n个节点的完全二叉树的高 h = log ? 2 n + 1 h=\log_2 n+1 h=log2?n+1(向下取整)
令 j = h ? i , 则 i = h ? j 。 令j=h-i,则i=h-j。 j=h?ii=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} n\times 2 \times 2^{-j} \times j=2n\times \sum_{j=\log_2 n}^{1} 2^{-j} \times j =j=h?11?2h?j×j=j=log2?n1?2log2?n+1?j×j=j=log2?n1?n×2×2?j×j=2n×j=log2?n1?2?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=1\times\frac{1}{2}+2\times\frac{1}{4}+3\times\frac{1}{8}+...+h\times\frac{1}{2^h} Sn?=j=h1?2?j×j=j=1h?2?j×j=1×21?+2×41?+3×81?+...+h×2h1?
① × 1 2 ①\times\frac{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=1\times\frac{1}{4}+2\times\frac{1}{8}+...+(h-1)\times\frac{1}{2^h}+h\times\frac{1}{2^{h+1}} 21?Sn?=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}}-h\times\frac{1}{2^{h+1}}=\frac{\frac{1}{2}(1-\frac{1}{2^n})}{1-\frac{1}{2}}-h\times\frac{1}{2^{h+1}}=1-\frac{1}{2^n}-\frac{h}{2^{h+1}} 21?Sn?=21?+41?+81?+...+2h1??h×2h+11?=1?21?21?(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,所以2n\times \sum_{j=\log_2 n}^{1} 2^{-j} \times j<4n Sn?<22n×j=log2?n1?2?j×j<4n

建堆的时间复杂度为O(n)

交换堆顶底元素后重建堆的时间复杂度

每次将堆顶元素与堆底元素进行交换后,需要将剩余待排序元素重新建堆。此时处理的是堆顶元素,即根节点。根节点位于第一层,关键字最多比较次数为 2 × ( h ? 1 ) 2\times(h-1) 2×(h?1)次。
上述过程共需进行n-1次(n为节点个数),故重建堆的总的关键字最多比较次数为 2 × ( h ? 1 ) × ( n ? 1 ) = 2 log ? 2 n ( n ? 1 ) 2\times(h-1)\times(n-1)=2\log_2 n (n-1) 2×(h?1)×(n?1)=2log2?n(n?1)

重建堆的时间复杂度为O(nlogn)

堆排序的时间复杂度为O(nlogn)+O(n)=O(nlogn)

空间复杂度

整个排序过程,包括初建堆、交换顶底元素、重建堆,未用到其他多余的空间,主要进行比较与交换工作,所以空间复杂度是O(1)

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-03-21 21:17:10  更:2022-03-21 21:19:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/9 1:48:08-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码