1. 程式人生 > >四、C++實現佇列(queue)資料結構

四、C++實現佇列(queue)資料結構

本文使用C++實現佇列資料結構,與棧一樣,佇列(queue)也是線性邏輯的資料結構,佇列結構同樣支援物件的插入和刪除,但是兩種操作的物件範圍分別被限制於隊尾隊頭,並且這兩種操作又分別被稱為入隊出隊

佇列結構的特點:先進先出(First in first out,FIFO)

一、佇列資料結構的實現

佇列資料結構的實現可通過對vector或則list類封裝得到,但是考慮到佇列內元素的移動,採用list結構更加高效,所以這裡使用C++的繼承機制,直接從list類繼承,並對部分函式進行再封裝重新命名,得到queue類。(list.h的實現見之前的部落格)

queue介面列表
操作 功能 物件
queue() 預設建構函式  
~queue() 預設解構函式  
size() 返回佇列內部成員數量 佇列
empty() 判斷佇列是否為空 佇列
enqueue(const T& e) 指定元素入隊 佇列
dequeue() 出隊 佇列
front() 反對隊頭的引用 佇列
display() 列印佇列內部結構 佇列
#pragma once
#include"list.h"

template<typename T>
class queue :public list<T>
{
public:
	//建構函式
	queue(){}
	~queue(){}
	//解構函式
	int size() { return list<T>::size(); }
	bool empty() { if (size()) return false; else return true; }
	void enqueue(const T& e) { insertAsLast(e); }
	T dequeue() { return remove(first()); }
	T& front() { return first()->data; }
	void display() { list<T>::display; }
};

二、佇列資料結構的應用

和日常生活中的許多排隊例子一樣,佇列結構憑藉著先進先出(FIFO)這一特點,很適合實現公平和高效的資源分配規則。例如windows作業系統的訊息機制就是基於佇列結構,而且我還知道有其他一些大型伺服器框架就是基於佇列的。

這裡利用佇列結構實現銀行視窗服務的模擬。設銀行有nWin個視窗,顧客按照隨機概率到達,且每個客戶需要隨機的服務時間,然後這些客戶選擇佇列最短的視窗進行排隊,每個客戶需要的服務時間結束後出隊。

#include<iostream>
#include"queue.h"
using namespace std;

struct client
{
	int window;  //所屬視窗
	int time;    //所需服務時間
};

int bestWindow(queue<client>* w, int n)   //搜尋出佇列長度最短的視窗號
{
	int minTime = w[0].size();
	int minWin = 0;
	for (int i = 1; i < n; i++)
	{
		if (minTime > w[i].size())
		{
			minTime = w[i].size();
			minWin = i;
		}
	}
	return minWin;
}

void simulation(int nWin, int servTime)   //視窗總數,總服務時間
{
	queue<client>* windows = new queue<client>[nWin];   //建立視窗

	for (int t = 0; t < servTime; t++)    //在服務時間內
	{
		cout << "-------第" << t + 1 << "個服務時間單元-------" << endl;
		//模擬銀行來新客人
		if (rand() % ( nWin+ 1))      //客人以rand()/(rand() + 1)的概率到達
		{
			client c;
			c.time = 1 + rand() % 10;
			c.window = bestWindow(windows, nWin);
			windows[c.window].enqueue(c);//客戶入隊
			cout << "-new client ! (" << c.time << "," << c.window << ")" << endl;
		}

		//模擬視窗服務客人
		for (int i = 0; i < nWin; i++)
		{
			cout << "-第" << i << "個視窗還剩" << windows[i].size() << "個客人" << endl;
			if (!windows[i].empty())  //若當前視窗前有佇列
			{
				windows[i].front().time--;
				if (windows[i].front().time == 0)   //此客戶服務結束
				{
					windows[i].dequeue();
				}
			}
		}
	}
	delete[] windows;   //有new就有delete
}


void main(int argc, char *argv[])
{
	//模擬銀行視窗服務

	simulation(4, 10000);
	getchar();
}