数据结构与算法分析---二叉堆

堆,又称为优先队列。虽然名为优先队列,但堆并不是队列。堆和队列是两种不同的数据结构,堆是树态的,队列是线性的。在队列中,我们可以向队列添加元素,取出的时候是按照进入队列的先后顺序取出元素的,先进先出;而在堆中,却不是按照元素添加的先后顺序,而是按照元素的优先级取出元素

二叉堆的特性:
1.父节点的键值总是优先于任何一个子节点的键值;
2.左右子树都是一个二叉堆

二叉堆的操作:
1)上浮:就是在末尾哪里插入数据之后,根据这个数据的优先级向上自动,比如插入21
在这里插入图片描述
2)下浮:就是取出最大优先级之后,要一层一层往下找出,例如取出13
在这里插入图片描述
例如上面的删除操作,最后一步的时候,26向上移动了,这就需要选择最后面的数据31来顶替他的位置。


二叉堆可以通过定义一个数组来实现。例如:
在这里插入图片描述
堆顶下标从1开始:
parent(i) = i/2;
leftChild = 2 *i;
rightChild = 2 *i+1;


#include <stdio.h>
#include <malloc.h>
#include <string.h>

#define DUISIZE 100

//插入数据
//插入最末尾,一层一层往上浮
void Insert(int date,int duidate[])
{
	int i=0;
	if(duidate[0]>=(DUISIZE-1)){
		printf("no memory");
		return;
	}
	duidate[0]++;//插入计数+1
	if(duidate[0]==1){//表示插入第一个数据
		duidate[1]=date;
		return;
	}
	 //如果当前父节点比插入的数据要大
	 //那就继续往上浮
	for(i=duidate[0];duidate[i/2]>date&&i>0;i=i/2){
		duidate[i]=duidate[i/2];
	}
	//来到这里说明已经找到插入date 的位置了
	duidate[i]=date;
}

//取出数据
//策略就是把最后一个数据,补到空白的地方
int GetDate(int duidate[])
{
	int i=0,child=0;
	//取出优先级最高的数据
	int returndate=duidate[1];
	//取出队列中最后的一个数据,并确计数-1
	int lastdate=0;
	if(duidate[0] ==0) return 0;//没有数据
	lastdate=duidate[duidate[0]];
	duidate[0]--;
	for(i=1;i*2<=duidate[0];i=child){
		//判断子的大小
		child=i*2;
		//child!=duidate[0]这个判断条件是防止末尾
		//哪里只有一个子节点的情况
		if(child!=duidate[0]&&duidate[child]>duidate[child+1]){
			//说明有节点比较小
			child++;
		}
		
		if(lastdate>duidate[child]){
			duidate[i]=duidate[child];//子节点较小的数网上移
		}else{ //如果最后的数据比较小,那就直接返回了
			break;
		}
	}
	duidate[i]=lastdate;
	return returndate;

}

void main(void)
{
	int maindate[DUISIZE],i=0,temp=0;
	int k[10]={13,55,74,21,5,69,44,23,41,99};
	memset(maindate,0,DUISIZE*sizeof(int));
	for(i=0;i<10;i++){
		Insert(k[i],maindate);
	}
	
	for(i=0;i<10;i++){
		temp=GetDate(maindate);
		printf("%2d ",temp);
	}
	printf("\n");
}


在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值