1. 程式人生 > >C++迴圈佇列的陣列實現

C++迴圈佇列的陣列實現

迴圈佇列的陣列實現

---------------------------------------------------------------------------- 博主這篇給大家帶來迴圈佇列的陣列實現。廢話不多說,我們開始工作。

相信大家對陣列並不陌生,而且佇列的陣列實現其實就是普通陣列加上隊頭隊尾兩個指標來進行佇列結構的控制。 而相比普通的陣列佇列,迴圈佇列的優點在於空間上的優化使用。普通佇列的隊頭資料出列的時候,這個資料所在的位置我們就不會再用了,久而久之,在空間儲存上就會造成浪費。而迴圈佇列就可以避免這個問題,並只有在滿列時才會進行擴容,來存放新的資料。 雖然對於空間儲存是優化,但對於我們來說,就要稍微用點腦jin去重新寫一下演算法來實現它。

博主接下來會把一些重要的功能給大家詳細講解,其他的如建構函式,解構函式,會在後面一起貼出來,大家到時候去看。 這是迴圈佇列的變數和函式,博主先給大家,後面我們要用到

template <class T>
class SeqQueue              //為了優化結構,將佇列改為迴圈佇列
{
private:
	T* dataArray;     //佇列陣列
	int front;        //佇列的頭指標
	int rear;        //佇列的尾指標
	int maxsize;      //佇列容量
	char Full_Empty;   //如果滿,Full_Empty='f',如果空Full_Empty='e',佇列不滿標識'b'
	void OverFlowProcess();       //溢位處理
public:
	SeqQueue(int size);       //建構函式,大小為size
	~SeqQueue();              //解構函式
	bool InQueue(const T& x);   //資料x入列
	bool OutQueue(T& outValue);      //隊頭資料出列,並將其值賦給outValue
	bool GetFront(T& frontValue);     //讀取隊頭資料值
	int GetSize()const;             //計算佇列使用長度
	void MakeEmpty();               //清空佇列
};

----------------------------------------------------------------------------------- 注意,從上圖我們可以看出,當rear==front的時候,我們是無法判斷它是空還是滿,因此,我們用了一個標識: char Full_Empty; //如果滿,Full_Empty=‘f’,如果空Full_Empty=‘e’,佇列不滿標識’b’

Full_Empty用來方便我們判斷佇列的狀態。 而且一開始我們的隊頭和隊尾是指向下標為[0]的,即定義

int rear=0;
int front=0;

然後我們要進行資料的入列

template <class T>
void SeqQueue<T>::InQueue(const T& x)
{
	if (rear == front)          //如果佇列為空或者滿
	{
		if (Full_Empty == 'f')                //如果為滿佇列
		{
			OverFlowProcess();
			dataArray[rear] = x;
			rear = (rear + 1) % maxsize;
			Full_Empty = 'b';
		}
		else                                   //如果為空
		{
			dataArray[rear] = x;
			rear = (rear + 1) % maxsize;
			if (rear == front)                       //考慮到rear=front=0;maxsize=1;的情況
			{
				Full_Empty = 'f';
			}
			else
			{
				Full_Empty = 'b';
			}
		}
	}
	else                                       //如果佇列不為空列也不為滿列
	{
		dataArray[rear] = x;
		rear = (rear + 1) % maxsize;
		if (rear == front)
		{
			Full_Empty = 'f';
		}
	}
}

--------------------------------------------------------------------------------------

溢位處理,進行擴容

OverFlowProcess() 在進行擴容的時候我們已經判斷為滿列。但是,根據其滿列位置的不同,我們也需要分成兩種情況:rear=0以及rear!=0 為什麼要這樣分呢,是因為在進行資料拷貝的時候,如果rear=0,此時front也是0,我們就可以直接從front拷貝到maxsize-1,而不會出現漏掉資料的情況。 如果rear!=0,我們就要分兩部分來進行拷貝,一部分是從front到maxsize-1。另一部分是從0到rear-1。 在這裡插入圖片描述 這時候進行擴容的時候要注意,我們要先將原陣列的內容拷貝到新陣列中,並且,front的位置是改變的,變為front+擴容的大小。

template <class T>
void SeqQueue<T>::OverFlowProcess()
{
	T* newArray = new T[maxsize + Increasement];
	if (newArray == NULL)
	{
		cerr << "儲存分配失敗" << endl;
		exit(1);
	}
	if (rear - 1 < 0)
	{
		for (int i = front; i < maxsize; i++)
		{
			newArray[i] = dataArray[i];               //拷貝到新陣列
		}
		maxsize = maxsize + Increasement;
		for (int i = maxsize - 1; i >= (front + Increasement); i--)
		{
			newArray[i] = newArray[i - Increasement];
		}
		front = front + Increasement;
		delete[]dataArray;
		dataArray = newArray;
	}
	else
	{
		for (int i = front; i < maxsize; i++)
		{
			newArray[i] = dataArray[i];               //拷貝到新陣列
		}
		for (int i = 0; i < rear; i++)
		{
			newArray[i] = dataArray[i];
		}
		maxsize = maxsize + Increasement;
		for (int i = maxsize - 1; i >= (front + Increasement); i--)
		{
			newArray[i] = newArray[i - Increasement];
		}
		front = front + Increasement;
		delete[]dataArray;
		dataArray = newArray;
	}
}

--------------------------------------------------------------------------------------

出列函式

出列函式我們則分成兩部分: ①,佇列為空,我們返回false,說明為空佇列 ②,佇列不為空,即滿列和介於滿列和空列直接的狀態,出資料, front=(front+1)%maxsize

template <class T>
bool SeqQueue<T>::OutQueue(T& outValue)
{
	if (rear==front)
	{
		if (Full_Empty == 'e')         //如果為空
		{
			return false;
		}
		else                          //如果為滿
		{
			outValue = dataArray[front];
			front = (front + 1) % maxsize;
			if (front == rear)
			{
				Full_Empty = 'e';               //考慮到rear=front=0;maxsize=1;的情況
			}
			else
			{
				Full_Empty = 'b';
			}
			return true;
		}
	}
	else                             //不為空也不為滿
	{
		outValue = dataArray[front];
		front = (front + 1) % maxsize;
		if (front == rear)
		{
			Full_Empty = 'e';
		}
		return true;
	}
}

-------------------------------------------------------------------------------------- 其他函式博主就不再介紹了,比較簡單,博主把完整版程式碼貼在下面,大家可以參考:

#ifndef SEQQUEUE_H
#define SEQQUEUE_H
#include <stdlib.h>
#include <iostream>
using namespace std;
const int Increasement = 1;

template <class T>
class SeqQueue              //為了優化結構,將佇列改為迴圈佇列
{
private:
	T* dataArray;     //佇列陣列
	int front;        //佇列的頭指標
	int rear;        //佇列的尾指標
	int maxsize;      //佇列容量
	char Full_Empty;   //如果滿,Full_Empty='f',如果空Full_Empty='e',佇列不滿標識'b'
	void OverFlowProcess();       //溢位處理
public:
	SeqQueue(int size);       //建構函式,大小為size
	~SeqQueue();              //解構函式
	void InQueue(const T& x);   //資料x入列
	bool OutQueue(T& outValue);      //隊頭資料出列,並將其值賦給outValue
	bool GetFront(T& frontValue);     //讀取隊頭資料值
	int GetSize()const;             //計算佇列使用長度
	void MakeEmpty();               //清空佇列

	void output();
};
#endif // !SEQQUEUE_H
#include "seqqueue.h"

template <class T>
SeqQueue<T>::SeqQueue(int size)
{
	maxsize = size;
	dataArray = new T[maxsize];           //建立動態陣列
	if(dataArray==NULL)
	{ 
		cerr << "儲存分配失敗" << endl;
		exit(1);
	}
	front = rear = 0;                //隊頭隊尾指標初始化
	Full_Empty = 'e';                 //佇列為空
}
template <class T>
void SeqQueue<T>::OverFlowProcess()
{
	T* newArray = new T[maxsize + Increasement];
	if (newArray == NULL)
	{
		cerr << "儲存分配失敗" << endl;
		exit(1);
	}
	if (rear - 1 < 0)
	{
		for (int i = front; i < maxsize; i++)
		{
			newArray[i] = dataArray[i];               //拷貝到新陣列
		}
		maxsize = maxsize + Increasement;
		for (int i = maxsize - 1; i >= (front + Increasement); i--)
		{
			newArray[i] = newArray[i - Increasement];
		}
		front = front + Increasement;
		delete[]dataArray;
		dataArray = newArray;
	}
	else
	{
		for (int i = front; i < maxsize; i++)
		{
			newArray[i] = dataArray[i];               //拷貝到新陣列
		}
		for (int i = 0; i < rear; i++)
		{
			newArray[i] = dataArray[i];
		}
		maxsize = maxsize + Increasement;
		for (int i = maxsize - 1; i >= (front + Increasement); i--)
		{
			newArray[i] = newArray[i - Increasement];
		}
		front = front + Increasement;
		delete[]dataArray;
		dataArray = newArray;
	}
}
template <class T>
void SeqQueue<T>::InQueue(const T& x)
{
	if (rear == front)          //如果佇列為空或者滿
	{
		if (Full_Empty == 'f')                //如果為滿佇列
		{
			OverFlowProcess();
			dataArray[rear] = x;
			rear = (rear + 1) % maxsize;
			Full_Empty = 'b';
		}
		else
		{
			dataArray[rear] = x;
			rear = (rear + 1) % maxsize;
			if (rear == front)                       //考慮到rear=front=0;maxsize=1;的情況
			{
				Full_Empty = 'f';
			}
			else
			{
				Full_Empty = 'b';
			}
		}
	}
	else                                       //如果佇列不為空列也不為滿列
	{
		dataArray[rear] = x;
		rear = (rear + 1) % maxsize;
		if (rear == front)
		{
			Full_Empty = 'f';
		}
	}
}
template <class T>
bool SeqQueue<T>::OutQueue(T& outValue)
{
	if (rear==front)
	{
		if (Full_Empty == 'e')         //如果為空
		{
			return false;
		}
		else                          //如果為滿
		{
			outValue = dataArray[front];
			front = (front + 1) % maxsize;
			if (front == rear)
			{
				Full_Empty = 'e';               //考慮到rear=front=0;maxsize=1;的情況
			}
			else
			{
				Full_Empty = 'b';
			}
			return true;
		}
	}
	else                             //不為空也不為滿
	{
		outValue = dataArray[front];
		front = (front + 1) % maxsize;
		if (front == rear)
		{
			Full_Empty = 'e';
		}
		return true;
	}
}
template <class T>
bool SeqQueue<T>::GetFront(T& frontValue)
{
	if (Full_Empty=='e')
	{
		return false;
	}
	else
	{
		frontValue = dataArray[front];
		return true;
	}
}
template <class T>
int SeqQueue<T>::GetSize()const
{
	if (Full_Empty == 'e')
	{
		return 0;
	}
	else
	{
		if (Full_Empty == 'b')
		{
			if (rear < front)
			{
				return (maxsize - front + rear);
			}
			return (rear - front);
		}
		if (Full_Empty == 'f')
		{
			return maxsize;
		}
	}
}
template <class T>
void SeqQueue<T>::MakeEmpty()
{
	rear = 0;
	front = 0;
}
template <class T>
SeqQueue<T>::~SeqQueue()
{
	delete[]dataArray;
}

template <class T>
void SeqQueue<T>::output()
{
	if (Full_Empty == 'e')
	{
		cout << "nothing" << endl;
	}
	else
	{
		for (int i = 0; i < maxsize; i++)
		{
			cout << dataArray[i] << endl;
		}
	}
}