一、定义:队列是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。称为先进先出线性表 ,简称FIFO。允许插入的一端称为队尾,允许删除的一端称为队头。
二、队列的顺序存储结构:存储在数组中,在数组头补取出元素,在数组尾部进行插入操作。缺点:每次出队都必须移动数组中的每个元素的位置
三、循环队列:队列的顺序存储结构的不足在于每次出队操作都需要移动数组中的元素,时间复杂度大大提高。循环队列很好的解决了这个缺陷。循环队列的思路为不改变队列中元素的位置,改变队列的头指针和尾指针。当队列进行出队操作的时候改变队列的头指针,让它指向原本队列中的第二个元素。
1、入队:尾指针加一,当尾指针到达队列尾部时队列未满则重头开始循环(尾指针重新等于零)
2、出队:头指针减一,当尾指针到达队列尾部时队列不为空则从头开始循环(头指针重新等于零)
3、队满:(尾指针+1)%队列容量==头指针
4、队列为空:头尾指针相等。
5、队列当前长度:(尾指针-头指针+队列容量)%队列容量
四、循环队列代码:
public class SqQueue
{
/// <summary>
/// 队列容量
/// </summary>
private int maxSize;
/// <summary>
/// 队列头指针
/// </summary>
private int front;
/// <summary>
/// 队列尾指针
/// </summary>
private int rear;
/// <summary>
/// 队列的容器
/// </summary>
private int[] data;
/// <summary>
/// 初始化一个空队列
/// </summary>
/// <param name="maxsize"></param>
public SqQueue (int maxsize)
{
maxSize = maxsize;
front = 0;
rear = 0;
data = new int[maxSize];
}
/// <summary>
/// 求队列的长度
/// </summary>
/// <returns>返回队列长度</returns>
public int QueueLength()
{
return (rear - front + maxSize) % maxSize;
}
/// <summary>
/// 入队操作
/// </summary>
/// <param name="e">入队元素</param>
/// <returns>返回成功与否</returns>
public bool EnQueue(int e)
{
//判断栈是否已满 尾指针加一求余队列的容量
if ((rear + 1) % maxSize == front)
return false;
data[rear] = e;
//尾指针向后移动一位
//若到队尾则转到数组头部
rear = (rear + 1) % maxSize;
return true;
}
/// <summary>
/// 队列出队操作
/// </summary>
/// <param name="e">出队元素</param>
/// <returns>返回成功与否</returns>
public bool DeQueue(ref int e)
{
//判断队空
if (front == rear)
return false;
e = data[front];
front = (front + 1) % maxSize;
return true;
}
}
五、队列的链式存储结构
1、简述:容器为单链表,只能尾进头出。简称链队列。
2、拥有头尾两个两个节点方便入队和出队,队头节点指向链队列的头节点。空队列的时候头尾节点相同。
六、链队列的基本操作实现
/// <summary>
/// 队列节点
/// </summary>
class QNode
{
public int data;
public QNode next;
}
class LinkQueue
{
/// <summary>
/// 队列头节点
/// </summary>
private QNode front;
/// <summary>
/// 尾节点
/// </summary>
private QNode rear;
/// <summary>
/// 队列初始化 当队列为空时头尾节点指向队列的头节点
/// </summary>
public LinkQueue()
{
front = new QNode();
rear = front;
}
/// <summary>
/// 入队操作
/// 尾指针指向新的元素
/// </summary>
/// <param name="e">入队元素</param>
/// <returns>返回成功与否</returns>
public bool EnQueue(int e)
{
QNode node = new QNode();
node.data = e;
node.next = null;
rear.next = node;
rear = node;
return true;
}
/// <summary>
/// 队列出队操作
/// 出队的节点为头节点的后继节点
/// </summary>
/// <param name="e">出队元素</param>
/// <returns>返回成功与否</returns>
public bool DeQueue(ref int e)
{
//判断对是否为空
if (rear == front)
return false;
QNode node = new QNode();
node = front.next;
e=node.data;
/*if (node.next ==null)
{
front.next = null;
}*/
front.next = node.next;
//判断在出队后队列是否为空
if (rear == node)
rear = front;
return true;
}
}