数据结构复习--栈和队列(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> { #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; } } }
实现:
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); } }