堆排序(HeapSort)的学习及代码
作者:互联网
文章目录
前言
提示:以下是本篇文章正文内容,下面案例可供参考
一、堆的概念
-
堆是一棵完全二叉树(完全二叉树可以理解为节点需从左往右连续)
-
孩子节点的大小均小于或.大于父节点(孩子节点大的是小根堆,反之则是大根堆)
二、堆化
将一个节点变成一个堆的结构,这里以大根堆为例
思路:可以知道要修改的节点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