利用向上调整或向下调整算法来直接将一个无序的数组转为一个大根堆或者小根堆

目录

堆的向上调整算法代码

建堆(利用AdjustUp来建造)

利用AdjustUp方法来建堆分析

堆的向下调整算法代码

建堆(利用AdjustDown来建造)

利用AdjustUp方法来建堆分析


堆的向上调整算法代码


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个条件同时转换一下方向就可以了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值