C#数据结构之队列(Quene)实例详解

2019-12-30 11:22:08丽君

所以:入列时rear++的操作,应该稍做修正,当rear到数组下标最大值时,让它置0,以便能循环利用 (见后面的代码)

另外还有一个问题:最开始时front与rear都为-1,即front==rear时表示队列为空,改成循环以后,有可能会出现rear在循环过程中碰到front的情况,即真正意义的上"满"状态,这时rear也同样等于front,这样就无法单纯的用rear==front来判断是满,还是空?这时可以浪费一个元素的位置,认为当rear+1==front时,队列就已经满了,虽然牺牲了一个元素的空间,但却换来了逻辑的正确性,还是值得的。

完整实现如下:


using System;
using System.Text;
namespace 栈与队列
{
  /// <summary>
  /// 循环顺序队列
  /// </summary>
  /// <typeparam name="T"></typeparam>
  public class CSeqQueue<T>:IQueue<T>
  {
    private int maxsize;
    private T[] data;
    private int front;
    private int rear;    
    public CSeqQueue(int size) 
    {
      data = new T[size];
      maxsize = size;
      front = rear = -1;
    }
    public int Count()     
    {
      if (rear > front)
      {
        return rear - front;
      }
      else
      {
        return (rear - front + maxsize) % maxsize;
      }
    }
    public void Clear() 
    {
      front = rear = -1;
    }
    public bool IsEmpty() 
    {
      return front == rear;      
    }
    public bool IsFull() 
    {      
      if (front != -1) //如果已经有元素出队过
      {
        return (rear + 1) % maxsize == front;//为了区分与IsEmpty的区别,有元素出队过以后,就只有浪费一个位置来保持逻辑正确性.
      }
      else
      {
        return rear == maxsize - 1;
      }      
    }
    public void Enqueue(T item) 
    {
      if (IsFull()) 
      {
        Console.WriteLine("Queue is full");
        return;
      }
      if (rear == maxsize - 1) //如果rear到头了,则循环重来(即解决伪满问题)
      {
        rear = 0;
      }
      else
      {
        rear++;
      }
      data[rear] = item;
    }
    public T Dequeue() 
    {      
      if (IsEmpty()) 
      {
        Console.WriteLine("Queue is empty");
        return default(T);
      }
      if (front == maxsize - 1) //如果front到头了,则重新置0
      {
        front = 0;
      }
      else
      {
        front++;
      }      
      return data[front];
    }
    public T Peek() 
    {
      if (IsEmpty()) 
      {
        Console.WriteLine("Queue is empty!");
        return default(T);
      }
      return data[(front + 1) % maxsize];      
    }
    public override string ToString()
    {
      if (IsEmpty()) { return "queue is empty."; }
      StringBuilder sb = new StringBuilder();
      if (rear > front)
      {
        for (int i = front + 1; i <= rear; i++)
        {
          sb.Append(this.data[i].ToString() + ",");
        }
      }
      else
      {
        for (int i = front + 1; i < maxsize; i++)
        {
          sb.Append(this.data[i].ToString() + ",");
        }
        for (int i = 0; i <= rear; i++)
        {
          sb.Append(this.data[i].ToString() + ",");
        }
      }
      return "front = " + this.front + " t rear = " + this.rear + "t count = " + this.Count() + "t data = " + sb.ToString().Trim(',');
    }
  }
}