C#实现循环顺序队列(队列)

 

 

    队列同栈相对,前者为先进先出(First In First In)。

 

    顺序队里中,使用数组存储数据,基本原理同顺序线性表和顺序栈。由于使用数组,所以必须事先定义数组的最大容量MaxSize,使用front表示队头位置(最先入元素),使用rear表示队尾元素(最后入元素),这样每进入一个元素,rear要自加一次,每取出一个元素,front也要自加1,这样的话,rear或front很快就会到达MaxSize,无法再添加新的元素。为了避免这种情况出现,使用循环机制,即,若rear到达Maxsize-1的位置时,如果还需要继续添加的话,rear重新变为0.这样,判断队列已满的条件是,(Rear + 1) % MaxSize == Front。

 

做如下规定:

1.空队列时,有rear=front=-1,要求这是充要条件,即满足rear=front=-1就是空队列,如果队列中没有元素,则要求,rear=front=-1。注意,不能靠rear=front来判断是否为空队列,因为当加入第一个元素的时候,rear=front=0,相等不是空队列的充分条件,还必须是rear和front都等于-1才行。

如果是向空队列中添加元素,则必须从0索引开始,即rear=front=0。

2.添加元素时,必须判断目前的rear与maxsize的关系,如果rear=maxsize-1,则rear要重新从0开始。

3.元素出队列时,必须判断front与maxsize和rear的关系,并依此修改front的值。修改后,如果rear+1=front,则表明此时队列中没有元素,必须按照1的要求,设置rear=front=-1。

 

 

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Queue { //队列接口 interface IQueueDs { int GetLength(); bool IsEmpty(); bool IsFull(); void In(T t); T Out(); T GetFront(); } //循环顺序队列类 class CirSeqQueue : IQueueDs { private int intMaxSize; private T[] tData; private int intFrontPointer;//队头指针 private int intRearPointer;//队尾指针 public int MaxSize { get { return this.intMaxSize; } set { this.intMaxSize = value; } } public T this[int i]// 只读 { get { return this.tData[i]; } } public int FrontPointer { get { return this.intFrontPointer; } set { this.intFrontPointer = value; } } public int RearPointer { get { return this.intRearPointer; } set { this.intRearPointer = value; } } public CirSeqQueue():this(20)//数组默认容量20 { } public CirSeqQueue(int size) { this.intMaxSize = size; this.tData = new T[size]; this.intRearPointer = -1; this.intFrontPointer = -1; } #region IQueueDs 成员 public int GetLength() { return (this.intRearPointer + this.intMaxSize - this.intFrontPointer) % this.intMaxSize; } public bool IsEmpty()//不能仅凭相等判断,还必须都等于-1。当向队列添加第一个要素时,有rear=front=0,显然这种情况不是空队列。 { return (this.intFrontPointer == -1 && this.intRearPointer == -1); } public bool IsFull() { return (this.intRearPointer + 1) % this.intMaxSize == this.intFrontPointer; } public void In(T t) { if (this.IsFull()) { Console.WriteLine("The Queue is full!"); return; } if (this.IsEmpty())//如果是向空队列添加数据,则front和rear都设置为0 { this.intFrontPointer = 0; this.intRearPointer = 0; this.tData[this.intRearPointer] = t; } else { if (this.intRearPointer == this.intMaxSize - 1)//判断是否需要循环,如果rear已经达到数组最大索引,则需要重新从0开始 { this.intRearPointer = 0; this.tData[this.intRearPointer] = t; } else { this.intRearPointer++; this.tData[this.intRearPointer] = t; } } } public T Out() { if (this.IsEmpty()) { Console.WriteLine("The queue has no elements!"); return default(T); } else { T t = this.tData[this.intFrontPointer]; if (this.intFrontPointer == this.intMaxSize -1)//判断是否退到最大索引处 { this.intFrontPointer = 0; } else { this.intFrontPointer++; } if (this.intRearPointer + 1 == this.intFrontPointer)//如果front比rear大1个,表明队列中已经没有数据,此时要其设置为空队列,即 { this.intFrontPointer = -1; this.intRearPointer = -1; } return t; } } public T GetFront() { if (this.IsEmpty()) { Console.WriteLine("The queue has no elements!"); return default(T); } return this.tData[this.intRearPointer]; } #endregion } class Program { static void Main(string[] args) { //测试 CirSeqQueue queue = new CirSeqQueue(5); queue.In(1); queue.In(2); queue.In(3); queue.In(4); queue.In(5); queue.In(6);//测试这个值无法加入,超出maxsize Console.ReadLine(); Console.WriteLine(queue.Out());//输出1 Console.WriteLine(queue.Out());//输出2 Console.ReadLine(); queue.In(1); queue.In(2); queue.In(3); queue.In(4);//这个值无法加入,超出maxsize queue.In(5);//这个值无法加入,超出maxsize queue.In(6);//这个值无法加入,超出maxsize Console.ReadLine(); while (!queue.IsEmpty()) { Console.WriteLine(queue.Out());//输出 3 4 5 1 2 } Console.ReadLine(); } } }

 

你可能感兴趣的:(C#.Net)