当前位置: 首页 > wzjs >正文

沧州哪里做网站百度账户安全中心

沧州哪里做网站,百度账户安全中心,启博云微分销,如何搭建自己的微信小程序商城堆排序 一、 堆的基本概念二、 堆排序的主要步骤:1. 构建大顶堆(Max-Heap)2. 排序过程3. 堆化的详细过程4. 堆排序的完整步骤总结5. 堆排序的时间复杂度6. 堆排序的空间复杂度 三、 举例讲解示例数组第一步:构建大顶堆1.1 找到最后…

堆排序

  • 一、 堆的基本概念
  • 二、 堆排序的主要步骤:
    • 1. 构建大顶堆(Max-Heap)
    • 2. 排序过程
    • 3. 堆化的详细过程
    • 4. 堆排序的完整步骤总结
    • 5. 堆排序的时间复杂度
    • 6. 堆排序的空间复杂度
  • 三、 举例讲解
    • 示例数组
    • 第一步:构建大顶堆
      • 1.1 找到最后一个非叶子节点
      • 1.2 从索引 1 开始堆化
      • 1.3 接下来堆化索引 0
      • 1.4 检验并判断是否需要重新堆化
      • 1.5 构建大顶堆结果
    • 第二步:排序过程
      • 2.1 第一次交换
        • 堆化过程:
      • 2.2 第二次交换
        • 堆化过程:
      • 2.3 第三次交换
        • 堆化过程:
      • 2.4 第四次交换
    • 最终排序结果
  • 四、 Python 实现示例
  • 总结

一、 堆的基本概念

堆是一种完全二叉树,可以分为两种类型:

  • 大顶堆(Max Heap):每个结点的值都大于或等于其左右子结点的值。堆顶(根节点)元素是整个堆中最大的。
  • 小顶堆(Min Heap):每个结点的值都小于或等于其左右子结点的值。堆顶(根节点)元素是整个堆中最小的。

堆排序通常使用大顶堆来实现升序排序。排序时,首先构建大顶堆,然后将堆顶元素与数组最后一个元素交换,再对剩余的部分重新构建大顶堆,如此循环,直到整个序列有序。


二、 堆排序的主要步骤:

1. 构建大顶堆(Max-Heap)

堆排序首先需要将输入的无序数组调整为一个大顶堆(Max-Heap)。大顶堆的特点是每个父节点的值都大于或等于其左右子节点的值。通过这个过程,我们可以确保堆顶(根节点)的元素是当前堆中最大的。

  • 具体步骤
    • 从最后一个非叶子节点开始,对每个节点进行“堆化”(heapify)操作,直到根节点。堆化的作用是确保每个子树的结构满足堆的性质。
    • 为什么从最后一个非叶子节点开始?
      因为叶子节点本身就是堆,只有非叶子节点可能不满足堆的性质,因此从最后一个非叶子节点开始堆化,可以确保堆化时每个子树都已经是有效的堆。

假设数组的长度是 n,那么最后一个非叶子节点的索引为 (n // 2) - 1。我们从该节点开始,依次进行堆化,直到堆化到根节点。

  • 堆化(Heapify)
    • 堆化的目标是,确保一个父节点大于其子节点。
    • 对于某个父节点,比较其左右子节点,选出较大的子节点,将父节点与较大的子节点交换位置,递归继续向下堆化,直到堆的性质满足。

2. 排序过程

构建好大顶堆后,我们进入排序阶段。此时,堆顶的元素是当前数组中的最大元素。我们将堆顶元素与数组的最后一个元素交换位置,将最大元素“移出”堆外。然后缩小堆的范围,并对新的堆顶元素执行堆化操作,保证堆顶元素仍然是最大值。重复这个过程,直到堆的大小缩小到 1。

  • 具体步骤
    1. 将堆顶元素(最大元素)与数组的最后一个元素交换。
    2. 将堆的大小减 1(即排好序的部分不再参与堆化)。
    3. 对堆顶元素执行堆化操作,保证剩下的部分仍然是大顶堆。
    4. 重复步骤 1 至步骤 3,直到堆的大小为 1。

3. 堆化的详细过程

堆化是堆排序中非常重要的一步。它的目标是从某个节点开始,调整树的结构使其满足堆的性质(即父节点的值大于或等于子节点的值)。堆化的过程可以分为以下几个步骤:

  1. 比较当前节点和其左右子节点的值,找到三者中最大的一个。
  2. 如果当前节点的值已经大于或等于其左右子节点的值,则堆化过程结束。
  3. 如果当前节点的值小于其子节点,则将当前节点与最大子节点交换。
  4. 交换后,需要继续对交换后的子树进行堆化操作,确保堆的性质。

4. 堆排序的完整步骤总结

  1. 构建大顶堆
    • 从最后一个非叶子节点开始,依次对每个节点进行堆化,构建大顶堆。
  2. 排序过程
    • 将堆顶元素与数组的最后一个元素交换,减小堆的大小。
    • 对新的堆顶元素执行堆化,恢复堆的性质。
    • 重复上述过程直到堆的大小为 1。

5. 堆排序的时间复杂度

  • 构建堆:需要进行 n / 2 次堆化,每次堆化的时间复杂度为 O(log n),所以构建大顶堆的时间复杂度为 O(n)。
  • 排序过程:每次将堆顶元素与最后一个元素交换后,都需要对剩余的部分执行堆化。每次堆化的时间复杂度为 O(log n),一共需要执行 n - 1 次交换,因此排序过程的时间复杂度为 O(n log n)。

因此,堆排序的总时间复杂度为 O(n log n),这是一个较为稳定的时间复杂度。

6. 堆排序的空间复杂度

堆排序是原地排序算法,除了原始数组外,不需要额外的存储空间。所以堆排序的空间复杂度为 O(1)


三、 举例讲解

示例数组

假设初始数组为:

[4, 10, 3, 5, 1]

我们目标是使用大顶堆来排序,使得排序后得到升序排列的数组。

第一步:构建大顶堆

1.1 找到最后一个非叶子节点

对于长度 n=5 的数组,最后一个非叶子节点索引为

floor(n/2) - 1 = floor(5/2) - 1 = 2 - 1 = 1

所以从索引 1 开始往前(包括索引 0)依次堆化。

1.2 从索引 1 开始堆化

索引 1 的元素是 10

  • 左子节点索引:2 * 1 + 1 = 3,对应元素 5
  • 右子节点索引:2 * 1 + 2 = 4,对应元素 1

比较:
10 与 5、1 比较,10 已经大于其两个子节点,无需交换。
堆化后子树保持:[10, 5, 1](索引 1 及其子节点)不变。

1.3 接下来堆化索引 0

索引 0 的元素是 4

  • 左子节点索引:2 * 0 + 1 = 1,对应元素 10
  • 右子节点索引:2 * 0 + 2 = 2,对应元素 3

比较:

  • 当前节点 4,与左子节点 10 和右子节点 3 比较,最大的值为 10(索引 1)。
  • 交换:将 4 与 10 交换,数组变为:
    [10, 4, 3, 5, 1]
    

1.4 检验并判断是否需要重新堆化

交换后,以原索引 1 的位置(现在值为 4)的子树需要重新堆化:

对于索引 1(当前值 4):

  • 左子节点索引:2 * 1 + 1 = 3,对应元素 5
  • 右子节点索引:2 * 1 + 2 = 4,对应元素 1
    比较:
  • 在 4、5、1 中,最大值是 5(索引 3),所以交换 4 与 5。
  • 交换后数组变为:
    [10, 5, 3, 4, 1]
    

索引 3(值 4)是叶子节点,无需继续堆化。

1.5 构建大顶堆结果

经过上述堆化过程,整个数组已经构建成大顶堆,数组状态为:

[10, 5, 3, 4, 1]
  • 根节点 10 为最大值
  • 对应的二叉树结构为:
            10/  \5    3/ \4   1
    

第二步:排序过程

排序过程的目标是不断把堆顶(最大值)交换到数组末尾,然后对剩余部分重新堆化。

2.1 第一次交换

  • 交换堆顶与最后一个元素
    当前数组:[10, 5, 3, 4, 1]
    交换索引 0 与索引 4(最后一个元素):
    交换后数组变为:

    [1, 5, 3, 4, 10]
    
  • 说明:此时最大值 10 固定在最后位置,不参与后续堆化。

  • 对剩余堆(索引 0 到 3)重新堆化
    子数组为:[1, 5, 3, 4],堆的大小为 4。

堆化过程:
  • 从索引 0 开始堆化。
    索引 0 的元素:1

    • 左子节点索引:1,值为 5
    • 右子节点索引:2,值为 3
      比较:最大值为 5(索引 1)。
      交换:将 1 与 5 交换,数组变为:
    [5, 1, 3, 4, 10]
    

    继续堆化索引 1(值为 1):

    • 左子节点索引:3,值为 4
    • 右子节点索引:4,不在堆的范围内(堆大小为 4)
      比较:最大值为 4(索引 3)。
      交换:将 1 与 4 交换,数组变为:
    [5, 4, 3, 1, 10]
    

    索引 3 为叶子节点,堆化结束。

排序后,堆调整完成,堆为:[5, 4, 3, 1],根节点为最大值 5。

2.2 第二次交换

  • 交换堆顶与堆的最后一个元素
    当前数组:[5, 4, 3, 1, 10]
    交换索引 0 与索引 3:
    交换后数组变为:

    [1, 4, 3, 5, 10]
    
  • 说明:当前最大值 5 固定在正确位置。

  • 对剩余堆(索引 0 到 2)重新堆化
    子数组为:[1, 4, 3],堆大小为 3。

堆化过程:
  • 对索引 0(值 1)堆化:

    • 左子节点索引:1,值为 4
    • 右子节点索引:2,值为 3
      最大值为 4(索引 1)。
      交换:将 1 与 4 交换,数组变为:
    [4, 1, 3, 5, 10]
    

    对索引 1(值 1):

    • 左子节点索引:3,不在堆范围内(堆大小为 3)
      堆化结束。

排序后,堆调整完成,堆为:[4, 1, 3]。

2.3 第三次交换

  • 交换堆顶与堆的最后一个元素
    当前数组:[4, 1, 3, 5, 10]
    交换索引 0 与索引 2:
    交换后数组变为:

    [3, 1, 4, 5, 10]
    
  • 固定最大值 4 在位置索引 2。

  • 对剩余堆(索引 0 到 1)重新堆化
    子数组为:[3, 1],堆大小为 2。

堆化过程:
  • 对索引 0(值 3)堆化:
    • 左子节点索引:1,值为 1
      3 大于 1,无需交换。
      堆化结束。

排序后,堆调整完成,堆为:[3, 1]。

2.4 第四次交换

  • 交换堆顶与堆的最后一个元素
    当前数组:[3, 1, 4, 5, 10]
    交换索引 0 与索引 1:
    交换后数组变为:

    [1, 3, 4, 5, 10]
    
  • 此时只剩下一个元素,不需要再堆化。

最终排序结果

经过上述所有交换和堆化,数组最终变为:

[1, 3, 4, 5, 10]

这就是堆排序完成后的结果,数组按升序排列。


四、 Python 实现示例

以下是一个简单的 Python 实现示例,帮助更好地理解具体实现步骤:

# 堆调整函数
def heapify(arr, heap_size, i):# 初始化最大值为当前节点索引largest = i# 计算左子节点的索引left = 2 * i + 1# 计算右子节点的索引right = 2 * i + 2# 如果左子节点存在(索引小于堆大小),且左子节点的值大于当前最大值if left < heap_size and arr[left] > arr[largest]:# 更新最大值索引为左子节点largest = left# 如果右子节点存在(索引小于堆大小),且右子节点的值大于当前最大值if right < heap_size and arr[right] > arr[largest]:# 更新最大值索引为右子节点largest = right# 如果最大值不是当前节点(说明需要调整)if largest != i:# 交换当前节点和最大值节点arr[i], arr[largest] = arr[largest], arr[i]# 递归调整交换后的子树,以保持堆的性质heapify(arr, heap_size, largest)# 堆排序函数
def heap_sort(arr):n = len(arr)  # 获取数组长度# 构建大顶堆for i in range(n // 2 - 1, -1, -1):# 从最后一个非叶子节点开始向上调整堆heapify(arr, n, i)# 排序过程for i in range(n - 1, 0, -1):# 将堆顶(最大值)与当前未排序部分的最后一个元素交换arr[0], arr[i] = arr[i], arr[0]# 对剩余未排序部分重新堆化,保持大顶堆性质heapify(arr, i, 0)# 示例用法
if __name__ == "__main__":array = [12, 11, 13, 5, 6, 7]  # 定义一个待排序数组print("原始数组:", array)  # 输出原始数组heap_sort(array)  # 调用堆排序函数对数组进行排序print("排序后的数组:", array)  # 输出排序后的数组

总结

我们可以总结堆排序的关键步骤:

  1. 构建大顶堆

    • 从最后一个非叶节点开始,依次对节点进行堆化,构建一个大顶堆。
  2. 排序过程

    • 将堆顶(最大值)与数组末尾交换,把最大值固定到正确位置;
    • 缩小堆的有效范围,对新的堆顶进行堆化,确保剩余部分仍然是大顶堆;
    • 重复以上过程直到排序完成。
http://www.dtcms.com/wzjs/29039.html

相关文章:

  • 知名企业网站规划书手机seo快速排名
  • 做网站济宁杭州seo招聘
  • 淮安那家公司做网站营销策划与运营方案
  • 商城手机网站制作上海seo推广方法
  • 成都app开发价格表电商seo名词解释
  • 有做酒席酒水网站吗广州各区正在进一步优化以下措施
  • 钓鱼网站搭建教程标题关键词优化报价
  • 自己免费制作app成都搜狗seo
  • 有没有做淘宝网站的网站建设全包
  • 教人做素食的网站网站建设找哪家好
  • 常州网站建设key de2345纯净版推广包
  • 网站建设基本流程淘宝运营培训班去哪里学
  • 网站建设中心联系方式优化网站排名工具
  • wordpress 聊天插件太原seo顾问
  • 企业网站免费源码seo网站有哪些
  • 网站域名打开一个网站
  • 网站设计方案怎么做推广赚佣金的平台
  • 口碑好的秦皇岛网站建设哪里有深圳百度推广竞价托管
  • 北海网站建设百度竞价排名商业模式
  • 阿里云安装wordpress天津百度搜索排名优化
  • 做网站去哪里做好如何网站优化排名
  • 怎么做套版网站网站seo置顶 乐云践新专家
  • 网站url 结构百度权重1是什么意思
  • 做软件开发视频网站最有效的推广学校的方式
  • 实时军事热点wifi优化大师下载
  • 营销型网站开发推广游戏优化是什么意思?
  • 品牌查询网官网查询北京优化推广公司
  • 南宁站建好就够用百度地图优化排名方法
  • 在家做网站维护兼职免费的网站申请
  • 本溪网站制作小视频关键词汇总