其他分享
首页 > 其他分享> > 堆排序(HeapSort)的学习及代码

堆排序(HeapSort)的学习及代码

作者:互联网

文章目录


前言


提示:以下是本篇文章正文内容,下面案例可供参考

一、堆的概念

  1. 堆是一棵完全二叉树(完全二叉树可以理解为节点需从左往右连续)
    在这里插入图片描述

  2. 孩子节点的大小均小于或.大于父节点(孩子节点大的是小根堆,反之则是大根堆)
    在这里插入图片描述

二、堆化

将一个节点变成一个堆的结构,这里以大根堆为例

在这里插入图片描述
思路:可以知道要修改的节点i的编号为 2 * i + 1 与 2 * i + 2 ,然后将他们的值与要修改的节点进行比较,若大于则交换,若不是最后一行节点在进行递归即可 。

代码如下(示例):

void HeapUp(int tree[],int n,int i)
{
    if(i >= n)
    {
        // 首先先排除掉 i 大于 n 的情况
        return;
    }
    int children1 = i * 2 + 1; //第一个孩子节点
    int children2 = i * 2 + 2; //第二个孩子节点
    int max = i; // 需要修改节点

    if(tree[max] < tree[children1]  && children1 < n) // 子节点大于 且 存在的情况下
    {
        max = children1;
    }
    if(tree[max] < tree[children2] && children2 < n)
    {
        max = children2;
    }

    if(max != i) // 则证明已被修改
    {
        swap(tree,max,i); // 将 tree 中 i与max的值对换
        HeapUp(tree,n,max);  //对下一层进行递归
    }


}

三 、构造一个完整的堆

思路:给出一串数字构造一个完整的堆,我们从倒数第二层开始依次往上进行堆化,如图所示
在这里插入图片描述
我们可以知道 最后一个节点的 位置是 n - 1,由 2*i+1 = n - 1 得他的父节点的位置是
(n-2)/2

代码如下(示例):

void build_heap(int tree[],int n)
{
    int last = (n -2) / 2;
    for(int i = last; i >= 0;i--)
    {
        HeapUp(tree,n,i);
    }
}

四、进行堆排序

思路:先将输入的数字构造成一个堆,在将根节点拿出,再将最后一位放到根节点,在重新对根节点堆化,如图所示
在这里插入图片描述
代码如图


void HeapSort(int tree[],int n)
{
    build_heap(tree,n); // 构造堆
    for(int i = n-1; i > 0; i--) //从最后一位元素与根结点进行互换在堆化
    {
        swap(tree,i,0); // 互换
        HeapUp(tree,i,0); //堆化
    }


}


五、总结

堆排序时间效率O(nlog2n)
空间效率O(1)
是一种不稳定的排序算法

标签:children2,堆化,int,堆排序,HeapSort,tree,节点,max,代码
来源: https://blog.csdn.net/Six23333/article/details/117918155