循环队列
由于数组在删除元素时,需要花费大量时间移动大量元素,因此基于数组的队列在执行出队操作时,速度很慢,很少有实际的应用,所以多采用循环队列的方式。
为了避免大量的数据移动,通常将一维数组中的各个元素看成是一个首尾相接的封闭的圆环,既第一个元素时最后一个元素的下一个元素,这种形式的顺序队列成为循环队列。
循环队列的代码如下:
using System; namespace Review { /// <summary> /// 循环队列类 /// </summary> public class Queue { #region "成员变量" private object[] _array;//存放元素的数组 private int _growFactor;//增长因子 private int _head;//队头指针 private const int _MinimumGrow=4;//最小增长值 private const int _ShrinkThreshold=0x20;//初始容量 private int _size;//当前元素个数 private int _tail;//队尾指针 #endregion #region "属性" /// <summary> /// 返回元素个数 /// </summary> public int Count { get{return this._size;} } #endregion #region "方法" /// <summary> /// 构造方法 /// </summary> public Queue() : this(_ShrinkThreshold,2f) { } /// <summary> /// 构造方法 /// </summary> /// <param name="capacity">初始容量</param> /// <param name="growFactor">增长因子</param> public Queue(int capacity,float growFactor) { //capacity指定初始容量,growFactor参数指定增长因子 if(capacity<0) { throw new ArgumentOutOfRangeException("capacity","初始容量不能小于0"); } if((growFactor<1.0)||(growFactor>10.0)) { //增长因子必须在1到10之间 throw ArgumentOutOfRangeException("growFactor","增长因子必须在1-10之间"); } this._array=new object[capacity]; this._head=0; this._tail=0; this._size=0; this._growFactor=(int)(growFactor*100f); } /// <summary> /// 出队 /// </summary> /// <returns></returns> public virtual object Dequeue() { if(this._size==0) { throw new InvalidOperationException("队列为空");//队列下溢 } object tmpObj=this._array[this._head];//出队 this._array[this._head]=null;//删除出队元素 //移动队头指针 this._head=(this._head+1)%this._array.Length; this._size--; return tmpObj; } /// <summary> /// 入队 /// </summary> /// <param name="obj"></param> public virtual void Enqueue(object obj) { if(this._size==this._array.Length) { //计算新容量 int capacity=(int)((this._array.Length*this._growFactor)/100L); if(capacity<(this._array.Length+_MinimumGrow)) { //至少要增加四个元素 capacity=this._array.Length+_MinimumGrow; } this.SetCapacity(capacity);//设置容量 } this._array[this._tail]=obj; this._tail=(this._tail+1)%this._array.Length;//移动队尾指针 this._size++; } /// <summary> /// 设置容量 /// </summary> /// <param name="capacity"></param> private void SetCapacity(int capacity) { //在内存空新开辟空间 object[] destinationArray=new object[capacity]; if(this._head<this._tail) { //元素搬家 Array.Copy(this._array,this._head,destinationArray,0,this._size); } else//当头指针在尾指针后面时 { //先搬头指针后面的元素,再搬数组头部到尾部指针之间的元素 Array.Copy(this._array,this._head,destinationArray,0,this._array.Length-this._head); Array.Copy(this._array,0,destinationArray,this._array.Length-this._head,this._tail); } this._array=destinationArray; this._head=0; this._tail=(this._size==capacity)? 0 : this._size; } #endregion } }