优先级队列和队列有啥区别?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了优先级队列和队列有啥区别?相关的知识,希望对你有一定的参考价值。
优先级队列 是不同于先进先出队列的另一种队列。每次从队列中取出的是具有最高优先权的元素优先队列的类定义
#include <assert.h>
#include <iostream.h>
$include <stdlib.h>
const int maxPQSize = 50; //缺省元素个数
template <class Type> class PQueue
public:
PQueue ( );
~PQueue ( ) delete [ ] pqelements;
void PQInsert ( const Type & item );
Type PQRemove ( );
void makeEmpty ( ) count = 0;
int IsEmpty ( ) const
return count == 0;
int IsFull ( ) const
return count == maxPQSize;
int Length ( ) const return count;
private:
Type *pqelements; //存放数组
int count; //队列元素计数
优先队列是0个或多个元素的集合,每个元素都有一个优先权或值,对优先队列执行的操作有1) 查找;2) 插入一个新元素;3) 删除.在最小优先队列(min priorityq u e u e)中,查找操作用来搜索优先权最小的元素,删除操作用来删除该元素;对于最大优先队列(max priority queue),查找操作用来搜索优先权最大的元素,删除操作用来删除该元素.优先权队列中的元素可以有相同的优先权,查找与删除操作可根据任意优先权进行.
最大优先权队列的抽象数据类型描述如ADT 9-1所示,最小优先队列的抽象数据类型描述与之类似,只需将最大改为最小即可.
ADT 最大优先队列的抽象数据类型描述抽象数据类型
M a x P r i o r i t y Q u e u e
实例 有限的元素集合,每个元素都有一个优先权
操作
Create ( ):创建一个空的优先队列
Size ( ):返回队列中的元素数目
Max ( ):返回具有最大优先权的元素
I n s e rt (x):将x插入队列
DeleteMax (x):从队列中删除具有最大优先权的元素,并将该元素返回至x
优先队列插入和删除元素的复杂度都是O(lgn),所以很快。
另一种描述方法是采用有序线性表,当元素按递增次序排列,使用链表时则按递减次序排列,这两种描述方法的删除时间均为( 1 ),插入操作所需时间为(n).
例:
假设我们对机器服务进行收费.每个用户每次使用机器所付费用都是相同的,但每个
用户所需要服务时间都不同.为获得最大利润,假设只要有用户机器就不会空闲,我们可以把
等待使用该机器的用户组织成一个最小优先队列,优先权即为用户所需服务时间.当一个新的
用户需要使用机器时,将他/她的请求加入优先队列.一旦机器可用,则为需要最少服务时间
(即具有最高优先权)的用户提供服务.
如果每个用户所需时间相同,但用户愿意支付的费用不同,则可以用支付费用作为优先权,
一旦机器可用,所交费用最多的用户可最先得到服务,这时就要选择最大优先队列. 参考技术A 队列就像平时买东西排队一样,从一个队伍的后面进入这个队伍,然后排队,直到走到队伍最前面(队首)才能出去。
队列就是采用FIFO(first in first out )原则模拟现实生活中这种排队模型的一种数据结构。
优先队列是对队列的进一步抽象,比如五个人排队,其中有一个是老年人,那么老年人就会自动被排到最前面。 参考技术B 优先级队列可以自定义优先级别在队列中优先查找级别高的数据,队列只能是先进先出,即先进入的数据级别高,后进入的级别低。
优先队列和堆
什么是优先队列?
优先队列也是一种队列,只不过不同的是,优先队列的出队顺序是按照优先级来的;在有些情况下,可能需要找到元素集合中的最小或者最大元素,可以利用优先队列ADT来完成操作,优先队列ADT是一种数据结构,它支持插入和删除最小值操作(返回并删除最小元素)或删除最大值操作(返回并删除最大元素);
这些操作等价于队列的enQueue
和deQueue
操作,区别在于,对于优先队列,元素进入队列的顺序可能与其被操作的顺序不同,作业调度是优先队列的一个应用实例,它根据优先级的高低而不是先到先服务的方式来进行调度;
如果最小键值元素拥有最高的优先级,那么这种优先队列叫作升序优先队列(即总是先删除最小的元素),类似的,如果最大键值元素拥有最高的优先级,那么这种优先队列叫作降序优先队列(即总是先删除最大的元素);由于这两种类型时对称的,所以只需要关注其中一种,如升序优先队列;
堆的代码
#include <stdio.h> #include <assert.h> #include<iostream> using namespace std; #define _CRT_SECURE_N0_WARNINGS 1 struct Heap{ int array[100]; int size; }; static void Swap(int *a, int *b) { int t = *a; *a = *b; *b = t; } //初始化 void HeapInit(Heap *pH, int source[], int size) { for (int i = 0; i < size; i++) { pH->array[i] = source[i]; } //更改堆的实际大小 pH->size = size; } //向下调整 大堆 //root 指的是下标 ------------->大根堆 void HeapAdjustDown(Heap* pH, int root) { int parent = root; while (true) { // 先判断有没有孩子(叶子结点) // 数组角度去想 -> 孩子的下标是否越界 // 只要判断左孩子的下标(因为是完全二叉树) int left = parent * 2 + 1; int right = parent * 2 + 2; if (pH->size < left) //越界 左孩子不存在 return; int MaxChild = left; if ((pH->size >= right) && (pH->array[right]>pH->array[MaxChild])) MaxChild = right; if (pH->array[MaxChild] < pH->array[parent]) return; //交换 swap(pH->array[MaxChild],pH->array[parent]); parent = MaxChild; } } //向上调整 大堆 void HeapAdjustUp(Heap* pH, int child) { int parent; while (child > 0) { parent = (child - 1) / 2; if (pH->array[parent] >= pH->array[child]) return; Swap(pH->array + parent, pH->array + child); child = parent; } } void HeapMakeHeap(Heap* pH) { //最后一个非叶子结点 last=size-1; //parent=(last-1)/2 = size/2-1; //所有非叶子结点的下标为[0 ,size/2-1] //从物理结构上来看 从后往前建堆 [最后一个非叶子结点size/2-1,0] for (int i = (pH->size - 2) / 2; i >= 0; i--) { HeapAdjustDown(pH, i); } } void HeapPop(Heap* pH) { pH->array[0] = pH->array[pH->size - 1]; pH->size = pH->size - 1; HeapAdjustDown(pH, 0); } int HeapTop(Heap* pH) { return pH->array[0]; } void HeapPush(Heap* pH,int data) { assert(pH->size < 100); pH->array[pH->size++] = data; HeapAdjustUp(pH, pH->size-1); } void Test() { int array[] = { 53, 17, 78, 9, 45, 65, 87, 23, 31 }; int size = sizeof(array) / sizeof(int); Heap heap; HeapInit(&heap, array, size); HeapMakeHeap(&heap); HeapPop(&heap); HeapPush(&heap, 100); printf("%d ", HeapTop(&heap)); printf("Create dump "); } int main() { Test(); return 0; }
以上是关于优先级队列和队列有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章