1 队列的概念和操作
1.1 队列的基本特征
队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。它是一种先进先出(First In First Out)的线性表,简称FIFO。允许插入的一端称为队尾,允许删除的一端称为队头
1.2 队列的基本操作
- 插入操作 ,在表尾插入元素 即入队
- 删除操作 ,返回并删除表头元素 即出队
2 队列的基本实现
队列属于线性表中的一种,那么就有顺序表和链表两种实现方式,但是不管哪种,都需要下面几个方法
Queue<T>() |
创建一个空的队列 |
void Enqueue(T s) |
往队列中添加一个新的元素 |
T Dequeue() |
移除队列中最早添加的元素 |
bool IsEmpty() |
队列是否为空 |
int Size() |
队列中元素的个数 |
2.1 队列的顺序存储实现
using System; using System.Text; namespace 数据结构.线性表.队列 { public class QueueArr<T> { private T[] Nodes; private int index; private int head; private int tail; /// <summary> /// 初始化栈 /// </summary> /// <param name="length"></param> public QueueArr (int length) { Nodes = new T[length]; this.index = 0; } /// <summary> /// 入队操作 /// </summary> /// <param name="node"></param> public void Enqueue (T node) { if (index == Nodes.Length) { ResizeLength(Nodes.Length * 2); } Nodes[tail] = node; tail++; index++; //StringBuilder sb = new StringBuilder(); //foreach (var i in Nodes) //{ // sb.Append($"{i}、"); //} //Console.WriteLine($"队列的长度是:{Size()},数组的长度是:{Nodes.Length},队列的内容是{sb}"); Console.WriteLine($"队列的长度是:{Size()}"); } /// <summary> /// 出队操作 /// </summary> /// <returns></returns> public T Dequeue () { if (index == 0) { return default; } T node = Nodes[head]; Nodes[head] = default(T); head++; if (index > 0 && index == Nodes.Length / 4) { ResizeLength(Nodes.Length / 2); } index--; //StringBuilder sb = new StringBuilder(); //foreach (var i in Nodes) //{ // sb.Append($"{i}、"); //} //Console.WriteLine($"取出的元素是:{node},队列的长度是:{Size()},数组的长度是:{Nodes.Length},队列的内容是{sb}"); Console.WriteLine($"取出的元素是:{node}"); return node; } /// <summary> // 重构队列 /// </summary> /// <param name="newLength"></param> public void ResizeLength (int newLength) { T[] newNodes = new T[newLength]; if (newLength > Nodes.Length) { for (var i = 0; i < Nodes.Length; i++) { newNodes[i] = Nodes[i]; } } else { for (var i = 0; i < index; i++) { newNodes[i] = Nodes[head++]; } tail = newLength; } Nodes = newNodes; head = 0; } /// <summary> /// 获取栈的长度 /// </summary> /// <returns></returns> public int Size () { return this.index; } /// <summary> /// 判断 /// </summary> /// <returns></returns> public bool IsEmpty () { return index == 0; } } }
2.2 队列的链式存储实现
using System; using 数据结构.链表; namespace 数据结构.线性表.栈 { public class QueueALinkList<T> { int index; /// <summary> /// 头结点 /// </summary> private Node<T> head; /// <summary> /// 尾节点 /// </summary> private Node<T> tail; /// <summary> /// 初始化队列 /// </summary> public QueueALinkList () { head = null; tail = null; } /// <summary> /// 入队操作 /// </summary> /// <param name="node"></param> public void Enqueue (T node) { Node<T> oldLastNode = tail; tail = new Node<T>(node); if (IsEmpty()) { head = tail; } else { oldLastNode.Next = tail; } index++; Console.WriteLine($"入栈的元素是{node};栈的长度是:{Size()}"); } /// <summary> /// 出队操作 /// </summary> /// <returns></returns> public T Dequeue () { var node = head; head = head.Next; index--; if (IsEmpty()) tail = null; Console.WriteLine($"出栈的元素是{node.Item};栈的长度是:{Size()}"); return node.Item; } /// <summary> /// 获取栈的长度 /// </summary> /// <returns></returns> public int Size () { return this.index; } /// <summary> /// 判断 /// </summary> /// <returns></returns> public bool IsEmpty () { return index == 0; } } }
3 C#中队列的实现
c#中也有队列的实现,即 命名空间System.Collections.Generic内的Queue,也提供了Dequeue,Enqueue方法,同时还提供了Peek方法(获取头部的元素但不删除它),没有反看源码,但是查资料C#内部是用的顺序存储的形式来实现队列的。貌似还是循环队列
队列的使用场景就多很多了,消息队列等等