目录
1.什么是堆
堆是一种完二叉树的数据结构,分为大根堆,和小根堆。
2.大根堆和小根堆
大根堆:父节点都大于子节点。 小根堆:父节点都小于字节点。


3.堆的特性
1.堆的本质就是个数组,这种树状的结构是我们想象出来的,实际进行排序的时候操作的是数组。
例:上面两个堆在数组中的实际存储如图
![]()

2.堆的父节点和子节点的下标存以下两种关系:
parent = (child-1)/2;左孩子和右孩子都可以,因为存在向上取整。
LeftChild = child * 2+1 ,RightChild = child *2 +2 。
3.大根堆的堆顶元素就是数组最大的数,小根堆的堆顶元素是数组最小的元素。
4.排序思路
1.用向下调整法建堆。
2.交换堆顶和堆底最后一个元素。(大根堆顶的元素是最大的,直接放到末尾就不用管了)
3.将n-1个数重新建堆。
4.重复以上过程。
5.向下调整法
为什么选择用向下调整法建堆,而不用向上调整法建堆,是因为,向下调整的效率比向上调整高很多,这里不做过多解释。
向下调整法也有它本身的局限性,他要求左右子树必须是大堆或者小堆,所以堆排必须必须从最后一个节点的父亲节点开始向下调整,不断向上调整,因为三个节点,要么是大堆,要么是小堆,不存在是不是堆的问题。
4.堆排序的实现
4.1向下调整法
void AdjustDown(int *a,int parent , int n)
{
int child = parent * 2 + 1;
while (child < n)
{
if (child+1<n && a[child + 1] > a[child])//找出左右孩子大的那一个
{
child++;
}
if (a[child] >a[parent])//比父亲大就交换
{
swap(&a[parent], &a[child]);
parent = child;
child = parent * 2 + 1;
}
else//没有发生交换说明已经是大堆(小堆)
{
break;
}
}
}
4.2堆排序
void HeapSort(int* a, int n)
{
//从最后一个孩子的父亲节点,由下向上 用向下调整法建堆。
for (int i = (n-1-1)/2;i >= 0; i--)//-1-1的原因是最后一个孩子的位置是(n-1)
{ //求父亲节点是(child-1)/2所以是(n-1-1)/2;
AdjustDown(a,i,n);
}
int end = n - 1;
while (end > 0)
{
swap(&a[end], &a[0]);
AdjustDown(a,0,end);
end--;
}
}

3947

被折叠的 条评论
为什么被折叠?



