《数据结构》学习笔记 19-20

本文介绍了堆数据结构及其在优先队列中的应用,详细解释了堆的基本操作如建堆、插入、删除等,并提供了具体的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


1 堆

堆实际上是一个完全二叉树的层次序列,可以用数组表示(所以完全二叉树的下表公式也通用~)

建堆过程

n不必将值一个个地插入堆中,通过交换形成堆
n假设根的左、右子树都已是堆,并且根的元素名为R。这种情况下,有两种可能

筛选法 重要
template <class T>
void MinHeap<T>::SiftDown(int position)
{
	int i=position;//标识父结点
	int j=2*i+1;//标识关键值较小的子结点		
	T temp=heapArray[i];//保存父结点
	//过筛
	while(j<CurrentSize){
	    if((j<CurrentSize-1)&&
		(heapArray[j]>heapArray[j+1]))
	j++;//j指向数值较小的子结点
		if(temp>heapArray[j]){
			heapArray[i]=heapArray[j];
			i=j;
			j=2*j+1;//向下继续
		}//end if
		else break;
	}//end if
	heapArray[i]=temp;
}

建堆
n从堆的第一个分支结点heapArray[CurrentSize/2-1]开始,自底向上逐步把以各分支结点为根的子树调整成堆
template<class T>
	void MinHeap<T>::BuildHeap()
	{
		//反复调用筛选函数
		for (int i=CurrentSize/2-1; i>=0; i--)
                SiftDown(i); 					
	} 

向上筛选调整堆 只需和父节点比较
template<class T>
void MinHeap<T>::SiftUp(int position) 
{//从position向上开始调整,使序列成为堆
	int temppos=position;
	T temp=heapArray[temppos];
	while((temppos>0)&&(heapArray[parent(temppos)]>temp))   //请比较父子结点直接swap的方法,一次swap要进行三次赋值
	{
	  heapArray[temppos]=heapArray[parent(temppos)];
	temppos=parent(temppos);
	}
	heapArray[temppos]=temp;
}

插入元素在尾部操作
template <class T>
bool MinHeap<T>::Insert(const T& newNode)
//向堆中插入新元素newNode
{
	if(CurrentSize==MaxSize)//堆空间已经满
		return FALSE;
	heapArray[CurrentSize]=newNode;
	SiftUp(CurrentSize);//向上调整
	CurrentSize++;
}

移出最小值(优先队列出队)
n可以将堆中最后一个位置上的元素(数组中实际的最后一个元素)移到根的位置上,利用siftdown对堆重新调整
template<T>
T& MinHeap<T>::RemoveMin()
{//从堆顶删除最小值
		if(CurrentSize==0)
		{
			//空堆
			cout<<"Can't Delete";
			exit(1);
		}	
else
	{
		//交换堆顶和最后一个元素
		swap(0,--CurrentSize);					
		if(CurrentSize>1)  // <=1就不要调整了  
		//从堆顶开始筛选
		SiftDown(0);						
		return heapSize[CurrentSize];
	}//end else
}

删除元素
template<class T>
bool MinHeap<T>::Remove(int pos, T& node)
{// 删除给定下标的元素
	if((pos<0)||(pos>=CurrentSize))
		return false;
	//指定元素置于最后
	T temp=heapArray[pos];
	heapArray[pos]=heapArray[--CurrentSize];	
	SiftUp(pos);//上升筛
	SiftDown(pos);//向下筛,不是SiftDown(0);	       不是很懂这个!!!
	node=temp;
	return true;
}

建堆效率O(n)
插入结点、删除普通元素和删除最小元素的平均时间代价和最差时间代价都是O(logn)

堆是优先队列的一种自然的实现方法。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值