一 大根堆与小根堆以及知识点
大根堆(大顶堆):是一颗完全二叉树,其父亲节点总是比叶子节点大。也就是大根堆的根节点最大
小根堆(小顶堆):是一颗完全二叉树,其父亲节点总是比叶子节点小。也就是大根堆的根节点最小
对一颗完全二叉树来说:length/2必为最大的非叶子节点,1为根节点,对父亲节点k来说,2*k 和2*k+1为其叶子节点。
二 说明
对需要进行从小到大排序的数组来说,采用大根堆,将一次大根堆排序后的根节点写入最后一个叶子节点(对应数组的最后一个),依次在堆排序就完成了整个排序。
注意:对数组来说,各节点为1,0节点不参与排序,也就是说:数组第一个元素不参与排序,数组元素为 length+1。
三 代码说明
//root 根节点
static void HeapAdjust(int k[], int length,int root)
{
int temp = k[root];
for (int i = root * 2; i <= length; i = i*2)
{
if (i<length && k[i] < k[i + 1])//左孩子 小于 右孩子
{
i++;//获取大的孩子节点的下标,然后与跟节点比较
}
if (k[i] <= temp)//类似与哨兵作用,在没有不需要交换时候说明已经完成此次的交换
{
break;
}
k[root] = k[i];
root = i;
}
k[root] = temp;//插入到该有的位置
}
void HeapSoft(int k[], int length)
{
//从最大的非树节点开始构造大根堆
for (int i = length / 2; i > 0;--i)
{
HeapAdjust(k, length, i);//构造大根堆 其根节点最大
}
for (int j = length; j > 1;--j)
{
Swap(k,1,j);//最大的放到最后一个
HeapAdjust(k,j-1,1);//从新构造root节点的大根堆
}
}
int k[11] = { -1,5, 1, 6, 4, 3, 9, 0, 7, 2, 8 };其中 -1不能进行排序