队列是先进先出的线性表,顾名思义,优先队列则是元素有优先级的队列,出列的顺序由元素的优先级决定。从优先队列中删除元素是根据优先权的高低次序,而不是元素进入队列的次序。优先队列的典型应用是机器调度等。

假设我们对机器服务进行收费。每个用户每次使用机器所付费用都是相同的,但每个用户所需要服务时间都不同。为获得最大利润,假设只要有用户机器就不会空闲,我们可以把等待使用该机器的用户组织成一个最小优先队列,优先权即为用户所需服务时间。当一个新的用户需要使用机器时,将他 /她的请求加入优先队列。一旦机器可用,则为需要最少服务时间(即具有最高优先权)的用户提供服务。如果每个用户所需时间相同,但用户愿意支付的费用不同,则可以用支付费用作为优先权,一旦机器可用,所交费用最多的用户可最先得到服务,这时就要选择最大优先队列。

1.概念

优先队列( priority queue)是0个或多个元素的集合,每个元素都有一个优先权或值,对优先队列执行的操作有 1) 查找; 2) 插入一个新元素; 3) 删除。在最小优先队列( min priority q u e u e)中,查找操作用来搜索优先权最小的元素,删除操作用来删除该元素;对于最大优先队列( max priority queue),查找操作用来搜索优先权最大的元素,删除操作用来删除该元素。优先权队列中的元素可以有相同的优先权,查找与删除操作可根据任意优先权进行。


描述优先队列最简单的方法是采用无序线性表。假设有一个具有n个元素的优先队列,如果采用公式化的线性表描述,那么插入操作可以十分方便的在表的右端末尾执行,插入操作的时间为O(1)。删除时必须查找优先权最大的元素,因此所需时间为O(n)。

若采用有序的线性表,则插入为O(n),删除为O(1)

2.实现

由上面描述可以知道,我们可以在线性表的基础上完成优先队列,只需要改变删除的操作,当删除时找到最大或最小的值即可。

我们可以直接继承线性表类线性表的2种实现方式:数组和链表

线性表的公式化实现:

 #ifndef LINEARLIST_H
#define LINEARLIST_H
#include<iostream>
#include<cstdlib>
#include<new>
using std::cout;
using std::endl;
template<class T>
class LinearList
{
public:
LinearList(int MaxListSize=);//构造函数
virtual ~LinearList();
bool IsEmpty()const
{
return length==;
}
int Length()const {return length;}
bool Find(int k,T& x)const;//返回第K个元素到中
int Search(T& x)const;//返回x的位置
LinearList<T>& Delete(int k,T& x);//删除位置k的元素,并将元素值存到x
LinearList<T>& Insert(int k,const T& x);//将x插入到k位置之后
void Output(std::ostream& out)const;//输出到流 protected:
int length;//线性表当前长度
int MaxSize;//最大长度
T *element;//线性表数组
}; class NoMem
{
public :
NoMem(){
cout<<"No Memory"<<endl;
//std::exit(1);
} }; class OutofBounds
{
public :
OutofBounds()
{
cout<<"Out of Bounds"<<endl;
//std::exit(1);
}
}; void my_new_handler()
{
throw NoMem();
} template<class T>
LinearList<T>::LinearList(int MaxListSize)
{
std::new_handler old_Handler=std::set_new_handler(my_new_handler);
MaxSize=MaxListSize;
element=new T[MaxSize];
length=; } template<class T>
LinearList<T>::~LinearList()
{
delete[]element;
MaxSize=;
length=;
} template<class T>
bool LinearList<T>::Find(int k,T&x)const
{
if(k<||k>length)
return false;
x=element[k-];
return true;
} template<class T>
int LinearList<T>::Search(T &x)const
{
int i=;
while(i<length&&element[i]!=x)
{
i++;
}
if(i==length) return ;
else return i+;
} template<class T>
LinearList<T>& LinearList<T>::Delete(int k,T &x)
{
if(Find(k,x))//存在位置k
{
for(int i=k;i<length;++i)
{
element[i-]=element[i];//k之后元素向前移动一位
}
length--;
return *this;
}
else
{
throw OutofBounds();
}
} template<class T>
LinearList<T>& LinearList<T>::Insert(int k,const T &x)
{
if(k<||k>length)
{
throw OutofBounds();
}
else if(length==MaxSize)
{
throw NoMem();
}
else
{
for(int i=length;i>k;--i)
{
element[i]=element[i-];//k之后元素向后移动一位
}
element[k]=x;
length++;
return *this;
}
} template<class T>
void LinearList<T>::Output(std::ostream& out)const
{
for(int i=;i<length;i++)
{ out<<element[i]<<" ";
}
} template<class T>
std::ostream& operator<<(std::ostream &out,const LinearList<T>& x)
{
x.Output(out);
return out;
} #endif // LINEARLIST_H

最大优先队列:

 #ifndef PRIORITYQUEUE_H
#define PRIORITYQUEUE_H
#include "LinearList.h" template<typename T>
class PriorityQueue:public LinearList<T>
{
public:
PriorityQueue(int MaxListSize=):LinearList<T>::LinearList(MaxListSize){};
PriorityQueue<T>& Insert(const T& x);
PriorityQueue<T>& Delete(T& x);
T Max() const;
~PriorityQueue(){};
//void Output(std::ostream& out)const;//输出到流
friend ostream& operator<< <>(ostream& output, const PriorityQueue<T>& x);
private:
size_t MaxIndex() const; }; //末端插入
template<typename T>
PriorityQueue<T>& PriorityQueue<T>::Insert(const T& x)
{
if (length>=MaxSize)
{
throw NoMem();
} element[length++] = x;
return *this;
} //找到最大值的索引(下标)
template<typename T>
size_t PriorityQueue<T>::MaxIndex() const
{
if (length == )
{
throw OutofBounds();
}
size_t maxNum = ;
for (size_t i = ; i < length; ++i)
{
if (element[i]>element[maxNum])
{
maxNum = i;
}
} return maxNum;
} //返回最大值
template<typename T>
T PriorityQueue<T>::Max() const
{
if (length==)
{
throw OutofBounds();
}
size_t maxNum = MaxIndex(); return element[maxNum];
} //取出最大值
template<typename T>
PriorityQueue<T>& PriorityQueue<T>::Delete(T& x)
{
if (length==)
{
throw OutofBounds();
} size_t maxindex = MaxIndex();
x = element[maxindex]; //元素前移
for (size_t i = maxindex; i < length-;++i)
{
element[i] = element[i + ];
}
--length;
return *this;
}
/*
template<typename T>
void PriorityQueue<T>::Output(std::ostream& out) const
{
if (length==0)
{
throw OutofBounds();
}
for (size_t i = 0; i < length;++i)
{
out << element[i]<<' ';
} out << endl;
}
*/
template<typename T>
ostream& operator<<(ostream& output,const PriorityQueue<T>& x)
{
x.Output(output);
return output;
}
#endif

测试:

 #include<iostream>
using namespace std; #include "PriorityQueue.h" int main()
{
PriorityQueue<int> testQ;
testQ.Insert();
testQ.Insert();
testQ.Insert();
testQ.Insert(); cout << "Queue is: " << endl;
cout << testQ << endl;
cout << "Queue size is: " << testQ.Length();
cout << endl;
cout << "Max in Queue is: " << testQ.Max();
cout << endl; int x;
testQ.Delete(x);
cout << "element deleted is: " << x<<endl; cout << "Queue is: " << endl;
cout << testQ << endl;
cout << "Queue size is: " << testQ.Length();
cout << endl;
cout << "Max in Queue is: " << testQ.Max();
cout << endl; return ;
}

优先队列(priorityqueue)的更多相关文章

  1. 【Java源码】集合类-优先队列PriorityQueue

    一.类继承关系 public class PriorityQueue<E> extends AbstractQueue<E> implements java.io.Serial ...

  2. [Swift]实现优先队列PriorityQueue

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  3. Java的优先队列PriorityQueue详解

    一.优先队列概述 优先队列PriorityQueue是Queue接口的实现,可以对其中元素进行排序, 可以放基本数据类型的包装类(如:Integer,Long等)或自定义的类 对于基本数据类型的包装器 ...

  4. Java优先队列PriorityQueue的各种打开方式以及一些你不知道的细节

    目录 Java优先队列PriorityQueue的各种打开方式以及一些你不知道的细节 优先队列的默认用法-从小到大排序 对String类用优先队列从大到小排序 通过自定义比较器对自定义的类进行从小到大 ...

  5. .NET 6 优先队列 PriorityQueue 实现分析

    在最近发布的 .NET 6 中,包含了一个新的数据结构,优先队列 PriorityQueue, 实际上这个数据结构在隔壁 Java中已经存在了很多年了, 那优先队列是怎么实现的呢? 让我们来一探究竟吧 ...

  6. [Swift]优先队列PriorityQueue(自定义数据结构)

    优先队列[priority queue] 普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除. 优先队列特点:在优先队列中,元素被赋予优先级. 当访问元素时,具有最高优先级的元素最先 ...

  7. 优先队列PriorityQueue实现 大小根堆 解决top k 问题

    转载:https://www.cnblogs.com/lifegoesonitself/p/3391741.html PriorityQueue是从JDK1.5开始提供的新的数据结构接口,它是一种基于 ...

  8. Python 标准库 —— 队列(Queue,优先队列 PriorityQueue)

    优先队列,有别于普通队列的先入先出(虽然字面上还是队列,但其实无论从含义还是实现上,和普通队列都有很大的区别),也有别于栈的先入后出.在实现上,它一般通过堆这一数据结构,而堆其实是一种完全二叉树,它会 ...

  9. 优先队列PriorityQueue&Lambda&Comparator

    今天翻阅<Labuladuo的算法小抄>时发现在使用优先队列的PriorityQueue解决一道hard题时(leetCode 23),出现了如下代码: ListNode mergeKLi ...

随机推荐

  1. Python中的深浅拷贝,赋值及引用

    简单来说,若对象a中存的是列表或字典等可变对象,b对a的浅拷贝只是对对象第一层的复制,修改b第二层的元素仍然会影响两个对象. 深拷贝则是不会影响原来的对象. import copy.copy() 浅拷 ...

  2. static静态属性和静态方法的原理与调用技巧

    这篇文章主要介绍了php面向对象中static静态属性和静态方法的调用,实例分析了static静态属性和静态方法的原理与调用技巧,需要的朋友可以参考下     本文实例讲述了php中static静态属 ...

  3. 每日一发linux命令

    很多用虚拟机的同学在向/tmp目录下进行解压的时候,会发现之前挂载的此目录空间不足,导致下一步无法进行(我在vmwaretools解压的时候就遇到了这个problem)…… 实际上,/tmp是可以进行 ...

  4. centos 6 编译安装httpd-2.4

    centos6 yum安装的apr版本已经不适用httpd-2.4版本了.所以,需要源码编译apr以及apr-util 1. 下载源码: cd /usr/local/src/ wget http:// ...

  5. RDLC报表系列(一) 简单的动态数据绑定和配置

    RDLC系列链接 RDLC报表系列(一) 简单的动态数据绑定和配置  RDLC报表系列(二) 行分组 RDLC报表系列(三) 总计和折叠 RDLC报表系列(四) 矩阵 RDLC报表系列(五) 简单的图 ...

  6. iOS 性能优化:Instruments

    对于每位 iOS 开发者来说,代码性能是个避不开的话题.随着项目的扩大和功能的增多,没经过认真调试和优化的代码,要么任性地卡顿运行,要么低调地崩溃了之……结果呢,大家用着不高兴,开发者也不开心. 其实 ...

  7. OC——NSArray和NSMutableArray

    /*---------------------NSArray---------------------------*/ //创建数组 NSArray *array1 = [NSArray arrayW ...

  8. 伪元素”:after” , “:before"

    伪元素就是源码html中不存在,而视觉上又存在的元素     简单用法: blockquote:before {      content: open-quote;      // 其他样式 } // ...

  9. RtlInitUnicodeString、IoCreateDevice、IoCreateSymbolicLink、IoDeleteDevice 四个 API 驱动函数的使用

    要解释"驱动对象",就得先从 DriverEntry() 说起: 做过C语言开发的都知道程序是从 main() 函数开始执行.在进行 Windows 驱动程序开发的时候没有 mai ...

  10. Gengxin讲STL系列——String

    衔接上一篇引导. 作为第一篇博客,就要大气一点. 可我好像并不知道怎么才能让自己的博客大气一点= =: 明天是我生日,自己先买个中文域名庆祝了一下…… 好了,废话说完了,结果博客也没大气到哪去……,正 ...