堆(heap)(c语言)

堆(heap)

这个堆不是堆栈。
堆是用完全二叉树储存。
堆是解决不是按照(时间或是说输入顺序)来进行排队,而是以优先的级别来排序。这就是优先队列了。

堆的特性

结构性:堆使用完全二叉树来存储,所以具备了完全二叉树的性质。所有子树的根结点比左右结点大。
有序性:任一结点的关键字是其子树所有结点的最大值(或最小值)

  1. 最大堆(MaxHeap):最大值
  2. 最小堆(MinHeap):最小值

优先队列

优先队列(Priority Queue):特殊的“队列”,取出元素的顺序是依照元素的优先权大小,而不是元素进入队列的先后顺序。
数组实现
1,插入:元素总是插入尾部
2,删除:查找最大元素(或最小)关键字。(从数组删除元素需要移动元素)
链表实现
1,插入:元素总是插入链表的头部
2,删除:查找最大(或最小)关键字。(直接删除结点)
有序数组实现
1,插入:找到合适位置,移动元素并插入。
2,删除:删除最后一个元素
有序链表实现
1,插入:找到合适位置,插入元素。
2,删除:删除最后一个元素
用树来实现
为了保证它在删除结点之后,树不会歪,就要考虑采用什么样的树。这个就是完全二叉树了。

最大堆(MaxHeap)

完全二叉树,每个结点的元素值不小于其子结点的元素值。

堆的结构体和定义

#define MaxData 10000 //定义哨兵
typedef struct HeapStruct *MaxHeap;
typedef enum { false, true } Boolean;
struct HeapStruct{
	ElementType *Elements;//储存堆元素的数组
	int Size;//堆当前元素个数
	int Capacity;//堆的最大容量
}

主要操作:
1,MaxHeap Create(int MaxSize):创建一个空的最大堆。

MaxHeap Create(int MaxSize){
	MaxHeap H = malloc(sizeof(struct HeapStruct));
	H->Elements=malloc((MaxSize+1)*sizeof(ElementType));//创建数组
	H->Size = 0;
	H->Capacity =MaxSize;
	H->Elements[0]=MaxData;//哨兵
}

2,Boolean IsFull(MaxHeap H):判断最大堆H是否已满。

Boolean IsFull(MaxHeap H){
	if(H->Size==Capacity)return 0;
	else return 1;
}

3,void Insert(MaxHeap H,ElementType item):将元素item插入最大堆H.

void Insert(MaxHeap H,ElementType item){
	int i;
	if(IsFull(H)){
		printf("最大堆已满");
		return}
	i = ++H->Size;//i指向插入后堆中的最后一个元素,并对size加1
	/*比较父结点,如果放到最大,就会有哨兵,
	这个哨兵就是最大的,让他不会在比较了。如果不用哨兵,就要加一个&&i>1*/
	for(;H->Elements[i/2]<item;i/2)
		H->Elements[i]=H-Elements[i/2];//向下过滤
	H->Elements[i]=item;//插入item
}

4,Boolean IsEmpty(MaxHeap H):判断最大堆H是否为空。

Boolean IsEmpty(MaxHeap H){
	if(H->Size==0) return 0;
	else return 1;
}

4,ElementType DeleteMax(MaxHeap H):返回H中最大元素(高优先级)

ElementType DeleteMax(MaxHeap H){
	int Parent,Child;
	ElementType MaxItem,temp;
	if(IsEmpty(H)){
		printf("最大堆为空");
		return}
	MaxItem = H->Elements[1];//取出结点
	//用最大堆中的一个元素从根结点向上过滤下层节点,调整
	temp = H->Elements[H->Size--];
	//判断有没有左右孩子
	for(Parent = 1;Parent*2 <= H->Size;Parent=Child){
		Child=Parent*2;
		//判断有没有右孩子,并找左右孩子中大的
		if((Child!=Size) && (H->Elements[Child] < H->Elements[Child+1]))
			Child++;
		if(temp >= H->Elements[Child]) break;
		else H->Elements[Parent] = H->Elements[Child];//将大孩子拉上来,并进入下一层,
	}
	H->Elements[Parent] = temp;
	return MaxItem;
}

最大堆的建立

  1. 通过插入操作:一个一个的插入。其时间复杂度为O(N log N)
  2. 在线性时间复杂度下建立最大堆。其时间复杂性为O(n)
    2.1将N个元素按输入顺序储存,先满足完全二叉树的结构特性
    2.2调整个结点位置,以满足最大堆的有序性
    所以在排序中会有一种堆排序方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值