數據結構復習--棧和隊列(2)--隊列
1.隊列:
隊列(Queue)是插入操作限電在表的尾部而其它操作限定在標的頭部進行的線性表,把進行插入操作的表成為隊尾(Rear),把進行其它操作的頭部成為隊頭(Front)。當隊列中沒有數據元素時稱為空隊列(Empty Queue)。
隊列通常記為:Q=(a1,a2....an),a1為隊頭元素,an為隊尾元素。這N個元素是按照a1,a2,...an的次序依次入隊的,出隊的次序與入隊相同,a1第一個出隊,an最後一個出隊。所以,隊列的操作是按照先進先出或後進後出的原則進行的。示意圖:
2.CLR中的隊列:Queue<T>
方法:
1.Enqueue() :入隊,放在隊尾
2.Dequeue():出隊,移除隊首元素,並返回被移除的元素
3.Peek():取出隊頭元素,不移除
4.Clear():清空元素
屬性:
Count():獲取隊列元素個數
3.順序隊列
用一片連續的存儲空間來存儲隊列中的數據元素,這樣的隊列成為順序隊列(Sequence Queue)。類似於順序棧,用一維數組來存放順序隊列中的數據元素。隊頭位置設在數組下標為0的端,用front表示,隊尾位置設在數組的另一端,用rear表示。front和rear隨著插入和刪除而變化。當隊列為空時 front=rear=-1。
鏈隊列:
隊列的另一種存儲方式是鏈式存儲,這樣的隊列成為鏈隊列(Linked Queue).同鏈棧一樣,鏈隊列通常用單鏈表表示,它的實現是單鏈表的簡化。所以,鏈隊列的節點的結構與單鏈表一樣。
循環隊列:
如上圖d中,如果再有一個數據元素入隊就會出現溢出,實際上隊列未滿,還有空閑控件,把這種現象稱為"假溢出",這是由於隊列"隊尾入隊頭出"的操作原則造成的,解決假溢出的方法是獎順序隊列看成是首尾相接的循環結構,頭尾指示器的關系不變,這種隊列叫循環隊列.
c#實現順序隊列:
/// <summary> /// 順序隊列 /// </summary> /// <typeparam name="T"></typeparam> public class SeqQueue<T> : IQueueDS<T> {View Code#region 初始化 private T[] data; private int count; private int front;//隊首 private int rear;//隊尾 public SeqQueue(int size) { data = new T[size]; count = 0; } public SeqQueue() : this(10) { } #endregion public int Count => count; public void Clear() { count = 0; front = rear = -1; } /// <summary> /// 出隊 /// </summary> /// <param name="item"></param> /// <returns></returns> public T Dequeue(T item) { if (count > 0) { T temp = data[front + 1]; front++; count--; return temp; } Console.WriteLine("隊列為空"); return default(T); } /// <summary> /// 入隊 /// </summary> /// <param name="item"></param> public void Enqueue(T item) { if (count == data.Length) { Console.WriteLine("隊列已滿"); return; } if (rear == data.Length - 1) { data[0] = item; rear = 0; return; } data[rear + 1] = item; count++; rear++; } public int GetLength() { return count; } /// <summary> /// 是否為空 /// </summary> /// <returns></returns> public bool IsEmpty() => count == 0; /// <summary> /// 取得隊首元素 /// </summary> /// <returns></returns> public T Peek() { T temp = data[front + 1]; return temp; } }
c#實現鏈隊列:
節點:
public class Node<T> { private T data; private Node<T> next; public Node(T data) { this.data = data; } public T Data { get { return data; } set { data = value; } } public Node<T> Next { get { return next; } set { next = value; } } }View Code
實現:
public class LinkQueue<T> : IQueueDS<T> { #region 初始化 private Node<T> front;//頭節點 private Node<T> rear;//尾節點 private int count;//元素個數 public LinkQueue() { front = null; rear = null; count = 0; } #endregion public int Count => count; public void Clear() { front = null; rear = null; count = 0; } /// <summary> /// 出隊 /// </summary> /// <param name="item"></param> /// <returns></returns> public T Dequeue(T item) { if (count == 0) { Console.WriteLine("隊列為空"); return default(T); } if (count == 1) { T temp = front.Data; front = rear = null; count = 0; return temp; } else { T temp = front.Data; front = front.Next; count--; return temp; } } /// <summary> /// 入隊 /// </summary> /// <param name="item"></param> public void Enqueue(T item) { Node<T> newNode = new Node<T>(item); if (count == 0) { front = newNode; rear = newNode; count = 1; return; } rear.Next = newNode; rear = newNode; count++; } public int GetLength() => count; public bool IsEmpty() => count == 0; /// <summary> /// 取隊首元素 /// </summary> /// <returns></returns> public T Peek() { if (front != null) { return front.Data; } return default(T); } }View Code
數據結構復習--棧和隊列(2)--隊列