队列

队列的定义及基本运算
队列(Queue)是插入操作限定在表的尾部而其它操作限定在表的头部进行的线性表。把进行插入操作的表尾称为队尾(Rear),把进行其它操作的头部称为队头(Front)。当对列中没有数据元素时称为空对列(Empty Queue)。
队列通常记为:Q= (a1,a2,…,an),Q是英文单词queue的第1个字母。a1为队头元素,an为队尾元素。这n个元素是按照a1,a2,…,an的次序依次入队的,出对的次序与入队相同,a1第一个出队,an最后一个出队。所以,对列的操作是按照先进先出(First In First Out)或后进后出( Last In Last Out)的原则进行的,因此,队列又称为FIFO表或LILO表。
这里写图片描述
队列的形式化定义为:队列(Queue)简记为Q,是一个二元组,
Q = (D, R)
其中:D是数据元素的有限集合;
R是数据元素之间关系的有限集合。
在实际生活中有许多类似于队列的例子。比如,排队取钱,先来的先取,后来的排在队尾。
队列的操作是线性表操作的一个子集。队列的操作主要包括在队尾插入元素、在队头删除元素、取队头元素和判断队列是否为空等。
与栈一样,队列的运算是定义在逻辑结构层次上的,而运算的具体实现是建立在物理存储结构层次上的。因此,把队列的操作作为逻辑结构的一部分,每个操作的具体实现只有在确定了队列的存储结构之后才能完成。队列的基本运算不是它的全部运算,而是一些常用的基本运算。

public interface IQueue<T> {
int GetLength(); //求队列的长度
bool IsEmpty(); //判断对列是否为空
void Clear(); //清空队列
void In(T item); //入队
T Out(); //出队
T GetFront(); //取对头元素
}

顺序队列

用一片连续的存储空间来存储队列中的数据元素,这样的队列称为顺序队列(Sequence Queue)。类似于顺序栈,用一维数组来存放顺序队列中的数据元素。队头位置设在数组下标为0的端,用front表示;队尾位置设在数组的另一端,用rear表示。front和rear随着插入和删除而变化。当队列为空时,front=rear=-1。
这里写图片描述
如果再有一个数据元素入队就会出现溢出。但事实上队列中并未满,还有空闲空间,把这种现象称为“假溢出”。这是由于队列“队尾入队头出”的操作原则造成的。解决假溢出的方法是将顺序队列看成是首尾相接的循环结构,头尾指示器的关系不变,这种队列叫循环顺序队列(Circular sequence Queue)。
这里写图片描述
当队尾指示器rear到达数组的上限时,如果还有数据元素入队并且数组的第0个空间空闲时,队尾指示器rear指向数组的0端。所以,队尾指示器的加1操作修改为:
rear = (rear + 1) % maxsize
队头指示器的操作也是如此。当队头指示器front到达数组的上限时,如果还有数据元素出队,队头指示器front指向数组的0端。所以,队头指示器的加1操作修改为:
front = (front + 1) % maxsize。
把循环顺序队列看作是一个泛型类,类名叫CSeqStack,“C”是英文单词circular的第1个字母。CSeqStack类实现了接口IQueue。用数组来存储循环顺序队列中的元素,在CSeqStack类中用字段data来表示。用字段maxsize表示循环顺序队列的容量,maxsize的值可以根据实际需要修改,这通过CSeqStack类的构造器中的参数size来实现,循环顺序队列中的元素由data[0]开始依次顺序存放。字段front表示队头,front的范围是0到maxsize-1。字段rear表示队尾,rear的范围也是0到maxsize-1。如果循环顺序队列为空,front=rear=-1。当执行入队列操作时需要判断循环顺序队列是否已满,如果循环顺序队列已满,(rear + 1) % maxsize==front,循环顺序队列已满不能插入元素。所以,CSeqStack类除了要实现接口IQueue中的方法外,还需要实现判断循环顺序队列是否已满的成员方法。

public class CSeqQueue<T> : IQueue<T> {
private int maxsize; //循环顺序队列的容量
private T[] data; //数组,用于存储循环顺序队列中的数据元素
private int front; //指示循环顺序队列的队头
private int rear; //指示循环顺序队列的队尾
//索引器
public T this[int index]
{
get
{
return data[index]; 
}
set
{
data[index] = value;
}
}
//容量属性
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;
}
}
//构造器
public CSeqQueue(int size)
{
data = new T[size];
maxsize = size;
front = rear = -1;
}
//求循环顺序队列的长度
public int GetLength()
{
return (rear-front+maxsize) % maxsize;
}
//清空循环顺序队列
public void Clear()
{
front = rear = -1;
}
//判断循环顺序队列是否为空
public bool IsEmpty()
{
if (front == rear)
{
return true;
}
else
{
return false;
}
}
//判断循环顺序队列是否为满
public bool IsFull()
{
if ((rear + 1) % maxsize==front)
{
return true;
}
else
{ 
return false;
}
}
//入队
public void In(T item)
{
if(IsFull())
{
Console.WriteLine("Queue is full");
return;
}
data[++rear] = item;
}
//出队
public T Out()
{
T tmp = default(T);
if (IsEmpty())
{
Console.WriteLine("Queue is empty");
return tmp;
}
tmp = data[++front];
return tmp;
}
//获取队头数据元素
public T GetFront()
{
if (IsEmpty())
{
Console.WriteLine("Queue is empty!");
return default(T);
}
return data[front+1];
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值