目录
堆的向上调整算法代码
void Swap(HPDataType* child , HPDataType* parent) {//交换堆中下标为child和parent的值
HPDataType tmp;
tmp = *child;
*child = *parent;
*parent = tmp;
}
void AdjustUp(HPDataType* a, int child) {//堆的向上调整(主要是插入数据的时候用)
//其中,参数HPDataType* a 是一个堆类型的指针,一般为数组类型.
//child为孩子节点在数组中的下标
int parent = (child - 1) / 2;//父节点的下标为子节点的下标-1除以2
while (child > 0) {//循环条件不能为parent>=0,在parent等于0时,
//child-1为 -1,再除以2则一直为0,产生死循环
if (a[child] < a[parent]) {//当子节点小于父节点时交换(***值和下标都要交换***)
Swap(&a[child], &a[parent]);//交换数组下标为child和parent的值
//交换parent和child的下标
child = parent;
parent = (child - 1) / 2;
}
else {
break;
}
}
}
建堆(利用AdjustUp来建造)
void BulidHeap(int* a,int n){
//方法一:利用AdjustUp方法来直接将数组转变为一个堆
//建堆方式一: O( N * logN )
for (int i = 1; i < n; i++) {
AdjustUp(a, i);//直接把这个数组的每一个数从下标为 0 的开始,到最后一个逐个进行向上提升。
//这样,for循环一结束的话,就把数组转变成了一个堆
}
}
#include <stdio.h>
int main(){
int a[] = {25,45,35,69,48,36,54,36,89};
int len = sizeof(a) / sizeof(a[0]);
BulidHeap(&a,len); //建造堆的方法
return 0;
}
利用AdjustUp方法来建堆分析
首先,我们创建了一个数组。
紧接着,我们算出来了它的长度
然后将数组的地址和长度作为创建堆的参数传入了建堆的方法中
接着我们只利用for循环和AdjustUp方法合做就创建好了一个堆。
这里是将数组从下标为 0 的节点开始,到数组尾节点,每一个节点都进行一次向上提升。
这样,在for循环结束的时候,其实数组内的数据已经变成了一个堆结构。
另外,如果你想创建一个小根堆或者大根堆,只需要将AdjustUp方法中的
a[child] < a[parent] 这个条件转换一下方向就可以了。
堆的向下调整算法代码
void Swap(HPDataType* child , HPDataType* parent) {//交换堆中下标为child和parent的值
HPDataType tmp;
tmp = *child;
*child = *parent;
*parent = tmp;
}
void AdjustDown(HPDataType* a, int size, int parent) {//向下调整(主要是在删除数据的时候使用)
//size是这个堆的节点个数,parent是父节点。
int child = parent * 2 + 1;//先假设小的孩子节点为左节点
while (child < size) {
if (child+1 < size && a[child + 1] > a[child]) {//如果右孩子比左孩子要小,则交换一下
//并且右孩子不一定存在,所以还需要child + 1 < size 这个条件
++child;
}
if (a[child] > a[parent]) {
Swap(&a[child], &a[parent]);//交换一下parent和child下标指向的值
//交换一下parent和child的下标
parent = child;
child = parent * 2 + 1;
}
else {//两个孩子节点都比父节点要大,则没必要再进行交换了
break;
}
}
}
建堆(利用AdjustDown来建造)
void BulidHeap(int* a,int n){
//方法二:利用AdjustDown方法来直接将数组转变为一个堆
//建堆方式二:O( N )
for (int i = (n - 1 - 1) / 2; i >= 0; i--) {//因为使用AdjustDown方法的前提是它的左右子树都得是堆才能进行(叶子节点无法使用AdjustDown方法)
//所以这里的初始条件将 i 设置为(n - 1 - 1) / 2 。
//其实 i 的值就是 末尾节点的 父节点。(父节点 = (孩子节点 - 1) / 2 )
//如果将一个未排序的数组,先将其以堆的形式进行排列(先不考虑是否成立)
//然后将其进行AdjustDown排序。
AdjustDown(a, n,i);
}
}
#include <stdio.h>
int main(){
int a[] = {25,45,35,69,48,36,54,36,89};
int len = sizeof(a) / sizeof(a[0]);
BulidHeap(&a,len); //建造堆的方法
return 0;
}
利用AdjustUp方法来建堆分析
首先,我们创建了一个数组。
紧接着,我们算出来了它的长度
然后将数组的地址和长度作为创建堆的参数传入了建堆的方法中
接着我们只利用for循环和AdjustDown方法合做就创建好了一个堆。
这里主要是因为AdjustDown方法的使用前提为其调整的左右子树必须都为堆才能进行。
所以将 i 的初始值设置为 (n - 1 - 1) / 2. (也就是末尾节点的父节点)
然后一直 将 i--操作,就将所有的非叶子节点都进行了向上排序
另外,如果你想创建一个小根堆或者大根堆,只需要AdjustDown中的 a[child + 1] < a[child] 和a[child] < a[parent] 这2个条件同时转换一下方向就可以了。