第11章 优先队列

拈花ヽ惹草 提交于 2019-12-10 19:04:19

优先队列的定义

优先队列也是一个以集合为基础的抽象数据类型
优先队列中的每一个元素都有一个优先级值。优先队列中元素x的优先级值记为p(x),它可以是一个实数,也可以是一个一般的全序集中的元素。优先级值用来表示该元素出列的优先级。
约定优先级值小的优先级高。亦可约定优先级值大的优先级高。

优先队列支持的基本运算有:
(1)Min(H):返回优先队列H中具有最小优先级的元素。
(2)Insert(x, H):将元素x插入优先队列H。
(3)DeleteMin(H):删除并返回优先队列H中具有最小优先级的元素。

优先级树的概念
优先级树是满足下面的优先级性质的二叉树:
(1)树中每一结点存储一个元素。
(2)任一结点中存储的元素的优先级值不大(小)于其儿子结点中存储的元素的优先级值即父结点的优先级不低于其儿子结点的优先级。
换句话说,越接近根的结点中的元素的优先级越高,越方便被访问,因为根最方便被访问。
相应的优先级树称为极小(大)化优先级树。

引入堆的概念并用堆来实现优先队列。
(1)堆的概念:如果一棵优先级树是一棵近似满二叉树,那么,这棵具有优先级性质的近似满二叉树(外形像堆)就叫做堆。
(2)用堆实现优先队列:Min(H)、Insert(x, H)和DeleteMin(H)运算的实现

用数组表示堆从而实现优先队列

(1) 用数组表示堆:
从1开始对堆的结点从根开始自上而下逐层、每层从左到右进行编号,然后让结点中的元素按编号在数组A中与下标对号入座
(2) 用数组表示堆的优点:
存储紧凑,空间利用率高
父子关系简单清晰:存放在A[i]的是结点i的元素, A[2i]和A[2i+1]分别是结点i的左和右儿子结点2i和2i+1的元素, A[i/2]是结点i的父结点的元素
在这里插入图片描述
堆排序算法基本思想:将无序序列建成一个堆,得到关键字最小(或最大)的记录;输出堆顶的最小(大)值后,使剩余的n-1个元素重又建成一个堆,则可得到n个元素的次小值;重复执行,得到一个有序序列,这个过程叫堆排序。

堆排序需解决的两个问题:
如何由一个无序序列建成一个堆?
如何在输出堆顶元素之后,调整剩余元素,使之成为一个新的堆?

第二个问题解决方法——筛选
方法:输出堆顶元素之后,以堆中最后一个元素替代之;然后将根结点值与左、右子树的根结点值进行比较,并与其中小者进行交换;重复上述操作,直至叶子结点,将得到新的堆,称这个从堆顶至叶子的调整过程为“筛选”。
在这里插入图片描述
在这里插入图片描述

int sift(T r[],int k,int m)
{
	int i,j;
	T x;
	i=k;x=r[i];j=2*i;
	while(j<=m)
	{
		if(j<m && r[j]>r[j+1])
			j++;//这里判断r[i]的右儿子r[j+1]是否存在,以及比较左右儿子的大小
		if(x>r[j])
		{
			r[i]=r[j];
			i=j;
			j*=2;
		}
		else break;
	}
	r[i]=x;
}		

在这里插入图片描述
在这里插入图片描述

void heapsort(T r[],int n)
{
	int i;
	T x;
	for(i=n/2;i>=1;i--)
		sift(r,i,n);
	for(i=n;i>=2;i--)
	{
		x=r[1];
		r[1]=r[i];
		r[i]=x;
		sift(r,1,i-1);
	}
}

哈夫曼树&哈夫曼算法&哈夫曼编码

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

typedef priority_queue<node,vector<node>,greater<node>> minq;
node huffman(vector<int> f)
{	//哈夫曼算法
	minq q;
	for(int i=0;i<f.size();i++)if(f[i])q.push(node(i,f[i]));
         while (q.size()>1){
             node *x=new node(q.top());q.pop();// 最小元素
             node *y=new node(q.top());q.pop();// 次小元素
             q.push(node(x,y));// 合并后重新入队
         }
	return q.top();// 哈夫曼树
}

在这里插入图片描述
在这里插入图片描述

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!