优先级队列
优先级队列是比栈和队列更专用的数据结构。但它在很多的情况下都很有用。像普通队列一样,优先级队列有一个队头和一个队尾,并且也是从队头移除数据项。不过在优先级队列中,数据项按关键字的值有序,这样关键字最小的数据项(或者在某些实现中是关键字最大的数据项)总是在队头。数据项插入的时候会按照顺序插入到合适的位置以确保队列的顺序。
//
// 优先队列
// TestList
//
// Created by chenshang on 14-2-8.
// Copyright (c) 2014年 chenshang. All rights reserved.
//
#ifndef TestList_PriorityQueue_h
#define TestList_PriorityQueue_h
//队列节点
//类模板声明
template<typename Type,typename Cmp> class PriorityQueue;
template<typename Type,typename Cmp>
class QueueNode
{
private:
friend class PriorityQueue<Type,Cmp>; //友元类访问私有变量
QueueNode(const Type item, QueueNode<Type,Cmp> *next=NULL)
:m_data(item),m_pnext(next){}
private:
Type m_data; //数据
QueueNode<Type,Cmp> *m_pnext; //指针
};
//类模板声明
template<typename Type>
class Compare
{ //处理一般比较大小
public:
static bool lt(Type item1,Type item2);
};
template<typename Type>
//函数实现
bool Compare<Type>::lt(Type item1, Type item2)
{
return item1<item2;
}
/*
对"<<"运算符的重载。
1、一般我们用的"<<"只能输出整型、实型等普通类型。
2、要想输出类类型,则必须对"<<"进行重载,其中一个参数为类类型对象。
3、为了方便对对象内部数据的操作,设置为friend友元函数。
4、为了能达到cout<<对象<<对象<<endl;的连续输出对象的效果,设置返回类型为引用。
参数:第一个为输出流对象。第二个为要输出的对象(为了防止产生临时对象、提高程序的效率,
将参数设置为引用类型,但引用类型又能改变实参的值,所以设置为const)。
*/
//struct的成员默认是公有的,方面在main函数中数据调用
struct SpecialData
{
//友元函数
friend ostream& operator<<(ostream& ,const SpecialData &);
int m_ntenor;
int m_npir;
};
//函数实现。
ostream& operator<<(ostream& os, const SpecialData &out)
{
os<<out.m_ntenor<<" "<<out.m_npir;
return os;
}
//处理特殊比较大小
class SpecialCmp
{
public:
static bool lt(SpecialData item1,SpecialData item2);
};
bool SpecialCmp::lt(SpecialData item1, SpecialData item2)
{
return item1.m_npir<item2.m_npir;
}
//Cmp is Designed for compare
template<typename Type,typename Cmp>
class PriorityQueue
{
public:
PriorityQueue():m_prear(NULL),m_pfront(NULL){}
~PriorityQueue()
{
MakeEmpty();
}
void MakeEmpty(); //make the queue empty
void Append(const Type item); //insert data
Type Delete(); //delete data
Type GetFront(); //get data
void Print(); //print the queue
bool IsEmpty() const
{
return m_pfront==NULL;
}
private:
QueueNode<Type,Cmp> *m_pfront; //前指针
QueueNode<Type,Cmp> *m_prear; //后指针
};
//清空操作
template<typename Type,typename Cmp>
void PriorityQueue<Type,Cmp>::MakeEmpty()
{
QueueNode<Type,Cmp> *pdel;
while(m_pfront)
{
pdel=m_pfront;
m_pfront=m_pfront->m_pnext;
delete pdel;
}
}
//添加数据
template<typename Type,typename Cmp>
void PriorityQueue<Type,Cmp>::Append(const Type item)
{
if(m_pfront==NULL)
{
m_pfront=m_prear=new QueueNode<Type,Cmp>(item);
}
else
{
m_prear->m_pnext=new QueueNode<Type,Cmp>(item);
m_prear=m_prear->m_pnext;
}
}
//出队列
template<typename Type,typename Cmp>
Type PriorityQueue<Type,Cmp>::Delete()
{
if(IsEmpty())
{
cout<<"There is no elements!"<<endl;
exit(1);
}
QueueNode<Type,Cmp> *pdel=m_pfront,*pmove=m_pfront;
//找出比队列头元素小的数据
//get the minimize priority's data
while(pmove->m_pnext)
{
//cmp:: lt is used for compare the two data, if the front one
//is less than the back, then return 1
if(Cmp::lt(pmove->m_pnext->m_data,pdel->m_pnext->m_data)){
pdel=pmove;
}
pmove=pmove->m_pnext;
}
//删除操作
pmove=pdel;
pdel=pdel->m_pnext;
pmove->m_pnext=pdel->m_pnext;
Type temp=pdel->m_data;
delete pdel;
return temp;
}
//出队头
template<typename Type,typename Cmp>
Type PriorityQueue<Type,Cmp>::GetFront()
{
if(IsEmpty())
{
cout<<"There is no elements!"<<endl;
exit(1);
}
QueueNode<Type,Cmp> *pdel=m_pfront,*pmove=m_pfront->m_pnext;
//get the minimize priority's data
while(pmove)
{
if(Cmp::lt(pmove->m_data,pdel->m_data))
{
pdel=pmove;
}
pmove=pmove->m_pnext;
}
return pdel->m_data;
}
template<typename Type,typename Cmp>
void PriorityQueue<Type,Cmp>::Print()
{
QueueNode<Type,Cmp> *pmove=m_pfront;
cout<<"front";
while(pmove)
{
cout<<"--->"<<pmove->m_data;
pmove=pmove->m_pnext;
}
cout<<"--->rear"<<endl<<endl<<endl;
}
#endif
#include <iostream>
using namespace std;
#include "PriorityQueue.h"
int main(){
PriorityQueue<int,Compare<int> > queue;
int init[10]={1,9,3,5,0,8,2,4,6,7};
for(int i=0;i<10;i++)
{
queue.Append(init[i]);
}
queue.Print();
queue.Delete();
queue.Print();
PriorityQueue<SpecialData,SpecialCmp> spe_queue;
int init2[5][2]={{34,2},{64,1},{18,3},{24,2},{55,4}};
//创建SpecialData
SpecialData data[5];
for(int i=0;i<5;i++)
{
data[i].m_npir=init2[i][1];
data[i].m_ntenor=init2[i][0];
}
for(int i=0;i<5;i++)
{
spe_queue.Append(data[i]);
}
spe_queue.Print();
//比较后指针的优先级
cout<<spe_queue.GetFront()<<endl<<endl;
spe_queue.Delete();
spe_queue.Print();
return 0;
}
运行结果: