优先队列----数据结构

这篇具有很好参考价值的文章主要介绍了优先队列----数据结构。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

概念

不知道你玩过英雄联盟吗?英雄联盟里面的防御塔会攻击离自己最近的小兵,但是如果有炮车兵在塔内,防御塔会优先攻击炮车(因为炮车的威胁性更大),只有没有兵线在塔内时,防御塔才会攻击英雄。所以你可以得出优先级:距离最近的炮车 > 炮车 > 距离最近的小兵 > 小兵 > 距离最近的英雄 > 英雄。

优先队列----数据结构,数据结构,数据结构,c++,算法

那什么是优先队列?首先它是一个队列,它的入队顺序没有发生改变,但是出队的顺序是根据优先级的高低来实现的,遍历队列,优先级高的先出队,有多个节点具有最高的优先级,选取遇到的第一个具有最高的优先级的节点。 

优先队列----数据结构,数据结构,数据结构,c++,算法

空队列

优先队列----数据结构,数据结构,数据结构,c++,算法

插入一个元素

优先队列----数据结构,数据结构,数据结构,c++,算法

插入第二个元素

优先队列----数据结构,数据结构,数据结构,c++,算法

 删除一个节点

优先队列----数据结构,数据结构,数据结构,c++,算法

优先队列----数据结构,数据结构,数据结构,c++,算法

上列情况是最普通的情况(无需多余的操作),显然如果删除的是队列中的最后一个节点,尾指针需要手动移动;如果删除的是队列中的第一个节点,头指针会自动移动。如果删除的队列只有一个节点,那头尾指针需要手动置空。所以总共有 2 种情况需要考虑。

队列的算法实现

队列的结构体定义

其中优先级的高低是自己定义的,你也可以令 0 为最高优先级,优先级数也不只有这 9 个。

#define MAX_SIZE 15
typedef int DateElem;

typedef struct _QNode
{
	int priority; //节点的优先级,9为最高优先级,0为最低优先级,优先级相同的取第一个
	DateElem date;
	struct _QNode* next;
}QNode;

typedef QNode* QueuePtr; //QueuePtr a; 就定义了一个指向结构体QNode的指针

typedef struct _Queue
{
	int length;    //队列长度
	QueuePtr head; //头指针
	QueuePtr tail; //尾指针
}Queue;

队列的初始化、判空、判满、插入

//队列的初始化,初始化为空队列
void initQueue(Queue* q)
{
	if (!q) //指向队头的指针为空
	{
		return;
	}

	q->head = NULL;
	q->tail = NULL;
	q->length = 0;
}

//判断队列是否为空
bool IsEmpty(Queue* q)
{
	if (!q) return false;

	if (q->head == NULL) //条件用 q->tail == NULL 也行
	{
		return true;
	}

	return false; //不为空
}


//判断队列是否为满
bool IsFull(Queue* q)
{
	if (!q) return false;

	if (q->length >= MAX_SIZE) //也可以用 q->length == MAX_SIZE
	{
		return true;
	}

	return false;
}

//入队
bool enterQueue(Queue* q, DateElem e, int priority)
{
	if (!q || IsFull(q))
	{
		cout << "队列已满" << endl;
		return false;
	}

	QNode* p = new QNode;

	//if (!q) return false; 一般不会生成失败

	p->priority = priority;
	p->date = e;
	p->next = NULL;

	//插入有两种情况
	if (IsEmpty(q)) //空队列
	{
		q->head = p;
		q->tail = p;
	}
	else //队列中已有元素
	{
		q->tail->next = p; //队列中的最后一个节点的next指针指向新加节点
		q->tail = p;	   //更新尾指针
	}

	q->length++;
	return true;
}

出队

唯一与普通队列有较大差别的就是队列的出队,其他的操作变化很小。

//遍历队列
bool popQueue(Queue* q,DateElem *out)
{
	if (!q || IsEmpty(q))
	{
		cout << "队列为空" << endl;
		return false;
	}

	if (!out)
	{
		cout << "无法传递删除节点的值" << endl;
		return false;
	}


	QNode** prev_node_next = NULL; //二级指针,指向优先级最高的节点的前一个节点的next指针
	QNode* prev_node = NULL; //指向优先级最高的节点的前一个节点
	QNode* temp = NULL,*last = NULL; //temp遍历队列,last指向temp指向的前一个节点

	prev_node_next = &(q->head); //最开始指向队头指针(也就是第一个节点的前一个节点的next指针),解引用就是指向第一个节点

	last = q->head; 
	temp = last->next; 

	while (temp != NULL)
	{
		if (temp->priority > (*prev_node_next)->priority)
		{
			cout << "找到了一个更高的优先级:" << temp->priority << endl;
			prev_node_next = &(last->next); //指向temp的前一个节点的next指针
			prev_node = last; //指向temp的前一个节点
		}
		last = temp;
		temp = temp->next;
	}

	*out = (*prev_node_next)->date; //传递出队元素的值
	temp = *prev_node_next;  // temp指向要删除节点
	*prev_node_next = (*prev_node_next)->next; //或者是 prev_node_next = & (*prev_node_next)->next;

	delete temp;
	q->length--;


	//情况一:删除节点后为空队列
	if (q->length == 0)
	{
		q->head = q->tail = NULL;
	}
	//情况二:删除的是尾节点
	else if ( *prev_node_next == NULL && prev_node != NULL)
	{
		q->tail = prev_node;
	}
	//情况三:删除的是首节点,与情况一不同的是删除节点后,队列不为空
	//情况四:普通情况
	//这两种情况遍历结束后的调整中头尾指针就弄好了

	return true;
}

如果你觉得我这里写得不好,嘻嘻,因为明明只需要用一级指针,我偏要用二级指针,这就是我与明明的区别,哈哈,好了不开玩笑,可以看看下图帮助理解。

优先队列----数据结构,数据结构,数据结构,c++,算法

队列的打印、清空、获取队首元素

//打印队列
bool Print(Queue* q)  
{
	if (!q) return false;

	if (IsEmpty(q))
	{
		cout << "队列为空" << endl;
	}

	QNode* p = q->head;
	cout << "队列中的元素:";
	while (p != NULL)
	{
		printf("%d[优先级%d] ", p->date,p->priority);
		p = p->next;
	}
	cout << endl;
	return true;
}
//清空队列
bool ClearQueue(Queue* q)
{
	if (!q || IsEmpty(q)) return false;

	QNode* temp = q->head, * tmp = NULL;

	while (temp != NULL)
	{
		tmp = temp->next;
		delete temp;
		temp = tmp;
	}

	q->length = 0;
	q->head = NULL;
	q->tail = NULL;
	return true;
}

//获取队头
bool GetHead(Queue* sq, DateElem* date)
{
	if (!date || !sq || IsEmpty(sq))return false;

	*date = sq->head->date; 
	return true;

}

主函数测试代码

int main(void)
{
	Queue* q = new Queue;
	DateElem e = -1;
	initQueue(q);

	for (int i = 0; i < 10; i++)
	{
		enterQueue(q, i + 2, i);
	}

	printf("队列中有%d个元素\n", q->length);

	Print(q);

	for (int i = 0; i < 5; i++)
	{
		if (popQueue(q, &e))
		{
			cout << "出队的元素是:" << e << endl;
		}
		else
		{
			cout << "出队失败" << endl;
		}
	}

	cout << "出队后,";
	Print(q);

	cout << "清空队列后,";
	ClearQueue(q);
	Print(q);

	//清理资源
	delete q;

	return 0;
}

 运行结果:

优先队列----数据结构,数据结构,数据结构,c++,算法文章来源地址https://www.toymoban.com/news/detail-737684.html

到了这里,关于优先队列----数据结构的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据结构:优先级队列(堆)

    队列是一种先进先出 (FIFO) 的数据结构 ,但有些情况下, 操作的数据可能带有优先级,一般出队 列时,可能需要优先级高的元素先出队列。 在这种情况下, 数据结构应该提供两个最基本的操作,一个是返回最高优先级对象,一个是添加新的对象 。这种数据结构就是 优先级

    2024年02月08日
    浏览(32)
  • 【数据结构】优先级队列——堆

    🧧🧧🧧🧧🧧个人主页🎈🎈🎈🎈🎈 🧧🧧🧧🧧🧧数据结构专栏🎈🎈🎈🎈🎈 🧧🧧🧧🧧🧧【数据结构】非线性结构——二叉树🎈🎈🎈🎈🎈 前面介绍过队列,队列是一种先进先出(FIFO)的数据结构,但有些情况下,操作的数据可能带有优先级,一般出队列时,可能

    2024年04月14日
    浏览(48)
  • 数据结构——优先队列c++详解

    百度百科定义 优先队列是0个或多个元素的集合,每个元素都有一个优先权或值,对优先队列执行的操作有1) 查找;2) 插入一个新元素;3) 删除.在最小优先队列(min priority queue)中,查找操作用来搜索优先权最小的元素,删除操作用来删除该元素;对于最大优先队列(max priority queue),查找操

    2024年02月09日
    浏览(29)
  • 数据结构-优先级队列(堆)

    文章目录 目录 文章目录 前言 一 . 堆 二 . 堆的创建(以大根堆为例) 堆的向下调整(重难点)  堆的创建  堆的删除 向上调整 堆的插入 三 . 优先级队列 总结 大家好,今天给大家讲解一下堆这个数据结构和它的实现 - 优先级队列 堆(Heap)是一种基于完全二叉树的数据结构,具有

    2024年02月08日
    浏览(35)
  • 数据结构 之 优先级队列(堆) (PriorityQueue)

    🎉欢迎大家观看AUGENSTERN_dc的文章(o゜▽゜)o☆✨✨ 🎉感谢各位读者在百忙之中抽出时间来垂阅我的文章,我会尽我所能向的大家分享我的知识和经验📖 🎉希望我们在一篇篇的文章中能够共同进步!!! 🌈个人主页:AUGENSTERN_dc 🔥个人专栏:C语言 | Java | 数据结构 ⭐个人

    2024年03月20日
    浏览(35)
  • 数据结构之优先级队列【堆】(Heap)

    目录 1. 优先级队列(Priority Queue) 2.堆的概念 3.堆的存储方式 4.堆的创建 5.用堆模拟实现优先级队列  6.PriorityQueue常用接口介绍 6.1 PriorityQueue的特点 6.2 PriorityQueue几种常见的构造方式 7.top-k问题 8.堆排序 本篇主要内容总结 (1)优先级队列底层是堆来实现的 (2)堆的本质是

    2024年02月01日
    浏览(43)
  • 数据结构 - 堆(优先队列)+ 堆的应用 + 堆练习

    1、本文章适合新学和复习用,都是用c语言实现的,包含了堆的讲解、堆的应用、堆的练习。 2、有图解和代码都注释,放心食用哦 那么开始: 一、什么是堆 堆(Heap)是计算机科学中一类特殊的数据结构,是最高效的优先级队列。堆通常是一个可以被看作一棵完全二叉树的数组

    2024年03月11日
    浏览(31)
  • 【数据结构】 优先级队列(堆)与堆的建立

    前面介绍过队列, 队列是一种先进先出(FIFO)的数据结构 ,但有些情况下,操作的数据可能带有优先级,一般出队列时,可能需要优先级高的元素先出队列,该中场景下,使用队列显然不合适。 比如:在手机上玩游戏的时候,如果有来电,那么系统应该优先处理打进来的电话

    2024年02月10日
    浏览(31)
  • 数据结构 - 6(优先级队列(堆)13000字详解)

    堆分为两种:大堆和小堆。它们之间的区别在于元素在堆中的排列顺序和访问方式。 大堆(Max Heap): 在大堆中,父节点的值比它的子节点的值要大。也就是说,堆的根节点是堆中最大的元素。大堆被用于实现优先级队列,其中根节点的元素始终是队列中最大的元素。 大堆

    2024年02月08日
    浏览(27)
  • Java 数据结构篇-用数组、堆实现优先级队列

    🔥博客主页: 【 小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍    文章目录         1.0 优先级队列说明         2.0 用数组实现优先级队列         3.0 无序数组实现优先级队列         3.1 无序数组实现优先级队列 - 入队列 offer(E value)         3.2 无序数组实现优先

    2024年02月04日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包