優先級隊列

優先級隊列

優先級隊列是比棧和隊列更專用的數據結構。但它在很多的情況下都很有用。像普通隊列一樣,優先級隊列有一個隊頭和一個隊尾,並且也是從隊頭移除數據項。不過在優先級隊列中,數據項按關鍵字的值有序,這樣關鍵字最小的數據項(或者在某些實現中是關鍵字最大的數據項)總是在隊頭。數據項插入的時候會按照順序插入到合適的位置以確保隊列的順序。


//
//  優先隊列
//  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;
}


運行結果:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章