理论基础:
队列(Queue)是插入操作限定在表的尾部而其它操作限定在表的头部进行的线性表。把进行插入操作的表尾称为队尾(Rear),把进行其它操作的头部称为队头(Front)。
对列的操作是按照先进先出(First In First Out)或后进后出( Last In Last Out)的原则进行的,因此,队列又称为FIFO表或LILO表。
与栈一样,队列的运算是定义在逻辑结构层次上的,而运算的具体实现是建立在物理存储结构层次上的。因此,把队列的操作作为逻辑结构的一部分,每个操作的具体实现只有在确定了队列的存储结构之后才能完成。
队列可以区分为顺序队列,链队列两种。
顺序队列类似于顺序栈,用一维数组来存放顺序队列中的数据元素。链队列同链栈一样,链队列通常用单链表来表示,它的实现是单链表的简化。
顺序队列在操作的过程中会出现“假溢出”。可以用循环顺序队列解决这种现象,因此,下面的代码将会实现循环顺序队列的主要操作。
C#实现:
1 接口定义
C#语言的泛型接口来表示队列,接口中的方法成员表示基本操作。为了表示的方便与简洁,把泛型队列接口取名为IQueue<T>(实际上,在C#中泛型队列类是从IEnumerable<T>、ICollection和IEnumerable接口继承而来,没有IQueue<T>泛型接口)。
队列接口IQueue<T>的定义如下所示:
Code
public interface IQueue<T>
{
/// <summary>
/// 队列长度
/// </summary>
/// <returns></returns>
int GetLength();
/// <summary>
/// 判断是否为空
/// </summary>
/// <returns></returns>
bool IsEmpty();
/// <summary>
/// 是否已满
/// </summary>
/// <returns></returns>
bool Full();
/// <summary>
/// 清空队列
/// </summary>
void Clear();
/// <summary>
/// 入队
/// </summary>
/// <param name="item"></param>
void In(T item);
/// <summary>
/// 出队
/// </summary>
/// <returns></returns>
T Out();
}
2 代码实现
实现提供的接口
Code
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 (front == (rear+1)%maxsize)
{
return true;
}
else
{
return false;
}
}
//入队
public void In(T item)
{
if (IsFull())
{
Console.Write("Queue is full");
return;
}
data[++rear] = item;
}
//出队
public T Out()
{
if (IsEmpty())
{
Console.Write("Queue is empty");
return;
}
return data[++front];
}
}
C#中的队列:
C#2.0以下版本只提供了非泛型的Queue类,该类继承了ICollection、IEnumerable和ICloneable接口。
C#2.0提供了泛型的Queue<T>类,该类继承了IEnumerable<T>、ICollection和IEnumerable接口。
以下程序说明了泛型Queue<T>类的主要方法,并对在我们自定义的队列类中没有出现的成员方法进行了注释,
关于泛型Queue<T>类的更具体的信息,可参考.NET Framework的有关书籍。
Code
public class Queue<T> : IEnumerable<T>, ICollection, IEnumerable
{
public void Clear();
//确定某元素是否在Queue<T>中。
//如果在Queue<T> 中找到 item,则为true;否则为false。
public bool Contains(T item);//从指定数组索引开始将Queue<T>元素复制到现有一维Array 中。
public void CopyTo(T[] array, int arrayIndex);
//移除并返回位于Queue<T>开始处的对象。
//从Queue<T>的开头移除的对象。
public T Dequeue();
//返回位于Queue<T>开始处的对象但不将其移除。
public T Peek();
//将Queue<T>元素复制到新数组。
public T[] ToArray();
//如果元素数小于当前容量的90%,
//将容量设置为Queue<T> 中的实际元素数。
public void TrimExcess();
}