C#資料結構回顧之迴圈佇列
阿新 • • 發佈:2019-01-22
引言:
佇列就和我們平常排隊買腎6一樣,排隊第一個肯定先能買到,也具有“先進先出”即所謂的FIFO,其實質用一維陣列來存放順序佇列中的資料元素。插入操作限定在表的尾部而其它操作限定在表的頭部進行的。隊頭位置設在陣列下標為0的端,用front表示;隊尾位置設在陣列的另一端,用rear表示。front和rear隨著插入和刪除而變化。當佇列為空時,front=rear=-1。但會隱藏一個隱患——假溢位(當隊尾指標last=MaxSize - 1時,佇列的前端可能還有許多,由於此前進行了刪除操作而產生的空的位置。這樣的情況,我們稱為假溢位現象。)為了解決假溢位的問題,將順序佇列看成是首尾相接的迴圈結構,即所謂的迴圈佇列,判斷隊空的條件是:rear==front,判斷隊滿的條件是:(rear + 1) % maxsize==front。求迴圈佇列中資料元素的個數可由(rear-front+maxsize)%maxsize公式求得。
定義介面:
//定義佇列的介面,對列的操作是按照先進先出(First In First Out)或後進後出( Last In Last Out)的原則進行的,因此,佇列又稱為FIFO表或LILO表
public interface IQueue<T>
{
int GetLength();//獲取佇列的長度
bool IsEmpty();//是否為空佇列
void Clear();//清空
void In(T item);//入隊
T Out();//出隊
T GetFrontItem();//取列頭元素
}
迴圈順序佇列的實體類實現:
幾個關鍵的操作:
- 訪問佇列元素:data[front+1]
- 滿隊:(rear + 1) % maxsize==front
- 空對:rear==front
- 遍歷:front++
public class CircularQueue<T> : IQueue<T>
{
#region 成員變數
private int maxsize; //迴圈順序佇列的容量
private T[] data; //陣列,用於儲存迴圈順序佇列中的資料元素
private int front; //指示迴圈順序佇列的隊頭
private int rear; //指示迴圈順序佇列的隊尾
#endregion
#region 索引器
public T this[int index]
{
get
{
return data[index];
}
set
{
data[index] = value;
}
}
#endregion
#region 成員屬性
//容量屬性
public int Maxsize
{
get
{
return maxsize;
}
set
{
maxsize = value;
}
}
//隊頭屬性
public int Front
{
get
{
return front;
}
set
{
front = value;
}
}
//隊尾屬性
public int Rear
{
get
{
return rear;
}
set
{
rear = value;
}
}
#endregion
#region 構造方法
public CircularQueue(int size)
{
data = new T[size];
maxsize = size;
front = rear = -1;
}
#endregion
#region 成員方法
//求迴圈順序佇列的長度
public int GetLength()
{
return (rear - front + maxsize) % maxsize;
}
//清空迴圈順序佇列:rear和front均等於-1。
public void Clear()
{
front = rear = -1;
}
//判斷迴圈順序佇列是否為空
public bool IsEmpty()
{
if (front == rear)
{
return true;
}
else
{
return false;
}
}
//判斷迴圈順序佇列是否為滿:(rear + 1) % maxsize==front
public bool IsFull()
{
if ((rear + 1) % maxsize==front)
{
return true;
}
else
{
return false;
}
}
//入隊:先使迴圈順序佇列的rear加1,front不變,然後在rear指示的位置新增一個新元素。
public void In(T item)
{
if (IsFull())
{
Console.WriteLine("Queue is full");
return;
}
data[++rear] = item;
}
//出隊:使隊頭指示器front加1,rear不變
public T Out()
{
T tmp = default(T);
//判斷迴圈順序佇列是否為空
if (IsEmpty())
{
Console.WriteLine("Queue is empty");
return tmp;
}
tmp = data[++front];
return tmp;
}
//獲取隊頭資料元素
public T GetFrontItem()
{
if (IsEmpty())
{
Console.WriteLine("Queue is empty!");
return default(T);
}
return data[front + 1];
}
//遍歷:
public void showQueue()
{
while (front!=rear)
{
Console.Write(data[front+1]+ "\t");
front++;
}
}
#endregion
}
迴圈佇列的簡單測試:
“`
CircularQueue cirQueue = new
CircularQueue(5);
cirQueue.In(2);
cirQueue.In(5);
cirQueue.In(8);
Console.WriteLine(“遍歷順序迴圈佇列:” + “\n”);
cirQueue.showQueue();