优先队列---二叉堆

优先队列---二叉堆:

二叉堆是一棵完全二叉树,最大堆(最小堆)中,所有根节点的键值都要比对应的子树要大(小)。

由于是完全二叉树,所以存储结构可以采用数组。

最大堆的创建:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<string.h>
#include<cstdlib>
#define INF 0x3f3f3f3f
typedef  int ElementType;
using namespace std;

struct HeapNode {
	ElementType *Elements;
	int Size;//当前个数
	int Capacity;//最大容量
};

typedef struct HeapNode *MaxHeap;

MaxHeap Create(int MaxSize)
{
	MaxHeap H = (MaxHeap)malloc(sizeof(struct HeapNode));
	H->Elements = (ElementType*)((MaxSize + 1) * sizeof(ElementType));
	H->Size = 0;
	H->Capacity = MaxSize;
	H->Elements[0] = INF;//哨兵
	return H;
}


最大堆的插入:

思想:先把待查元素放在数组的最后一个位置,然后和它的父亲去比较大小,如果比他父亲节点值大,则和它父亲互换,然后再依次和父亲节点比较大小,直到比父亲节点值小为止。为了减少互换的操作,可以先去找到最后待查元素的位置再去放(这样就有一个空穴)。---这一策略叫做上滤(空穴往上走)

数组0处放哨兵,卡住边界。

 

void Insert(MaxHeap H, ElementType item)
{
	if (H->Size >= H->Capacity)
	{
		cout << "满" << endl; return;
	}
	int i = ++H->Size;
	for (; H->Elements[i / 2] < item; i /= 2)//0处有哨兵。
		H->Elements[i] = H->Elements[i / 2];//上面的往下面走。直到i的父节点中的值大于item。
	H->Elements[i] = item;//放
}

 

最大堆的删除:

思想:把根节点元素返回。数组最后一个元素(tmp)先放在根节点位置(1位置),然后再去调整堆的顺序性,类似于插入,根节点元素值和儿子节点最大值相比较,如果前者比后者小,就互换,依次互换下去,直到tmp大于两个儿子节点的大小位置。

为了减少互换的操作,同样可以先找到tmp最后放的位置,由于这次空穴往下走,所以该策略叫做下滤

 

ElementType DeleteMax(MaxHeap H)
{
	int parent, child;
	ElementType maxitem, tem;
	if (H->Size == 0) { cout << "空" << endl; return; }
	maxitem = H->Elements[1];//最大值,便于后面返回。
	tem = H->Elements[H->Size--];
	for (parent = 1; parent * 2 <= H->Size; parent = child)
	{
		child = parent * 2;
		if (child != H->Size&&H->Elements[child] < H->Elements[child + 1])
			child++;
		if (tem >= H->Elements[child])break;
		else H->Elements[parent] = H->Elements[child];//下面的往上走,直到遇到tem大于下面的两个儿子为止。

	}
	H->Elements[parent] = tem;//放
	return maxitem;
}

 

 

最大堆的建立:

方法1:通过插入操作,依次将N个元素插入一个初始化为空的堆中。时间复杂度为O(NlogN)。

 

方法2:先将N个元素按输入顺序存入数组,然后调整各个节点的位置,以满足最大堆的有序性。

调整办法:从倒数第一个有儿子的节点开始依次调整,这样就能保证下面的堆序。类似于删除的操作,每次将要调整的子堆根节点拿出来,然后下滤,找到根节点的位置,放入即可。

这种方法的时间复杂度为是N。

void PercDown(MaxHeap H ,int p )
{
	int Parent, Child;
	ElementType X;
	X  = H->Elements[p];
	for (Parent = p; Parent * 2 <= H->Size; Parent = Child )
	{
		Child  = Parent  * 2;

		if ((Child != H->Size) && (H->Elements[Child]<H->Elements[Child + 1]))
			Child++;
	   
		if (X  >= H->Elements[Child]) break;    
		else   
			H->Elements[Parent] = H->Elements[Child];

	}
	H->Elements[Parent] = X;
}
void BuildHeap(MaxHeap H )
{
	 int i;
	  for (i  = H->Size / 2; i>0; i--)        
		  PercDown(H, i );
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值