队列

描述

1.只允许一端插入另一端删除的线性表

特性

先进先出,后进后出
image.png

顺序存储造成假溢

系统作为队列用的存储区还没有满,但队列却发生了溢出
解决方案:
<1>使用循环队列
<2>所有元素向前平移(占用0至rear-front-1)
<3>设置flag判断队列满

循环队列

/// <summary>
/// 队列
/// </summary>
namespace DataStruct.Queue
{
    /// <summary>
    /// 循环队列
    /// </summary>
    /// <typeparam name="T">数据类型</typeparam>
    class CirQueue<T> : IQueue<T>, IEnumerable<T>
    {
        /// <summary>
        /// 队列大小
        /// </summary>
        private const int MAX_SIZE = 10;
        /// <summary>
        /// 数据域
        /// </summary>
        private T[] data;
        /// <summary>
        /// 队尾
        /// </summary>
        private int rear;
        /// <summary>
        /// 队头
        /// </summary>
        private int front;
        /// <summary>
        /// 循环队列构造器
        /// </summary>
        public CirQueue(int size=MAX_SIZE)
        {
            this.data = new T[size];
            this.front = this.rear = 0;
        }
        /// <summary>
        /// 入队
        /// </summary>
        /// <param name="val">入队元素</param>
        public void Enter(T val)
        {
            if(IsFull())
                throw new IndexOutOfRangeException("队列满");
            this.data[this.rear] = val;
            this.rear = (this.rear + 1) % MAX_SIZE;
        }
        /// <summary>
        /// 出队
        /// </summary>
        /// <returns>返回出队元素</returns>
        public T Out()
        {
            if (IsEmpty())
                throw new IndexOutOfRangeException("队列空");
            var val = this.data[this.front];
            this.front = (this.front + 1) % MAX_SIZE;
            return val;
        }
        /// <summary>
        /// 队列元素个数
        /// </summary>
        public int Count { get => (this.rear-this.front)+MAX_SIZE%MAX_SIZE; }
        /// <summary>
        /// 判断队列空
        /// </summary>
        /// <returns>返回是否空</returns>
        public bool IsEmpty() => this.rear == this.front;
        /// <summary>
        /// 判断队列满
        /// </summary>
        /// <returns>返回是否满</returns>
        public bool IsFull() => (this.rear + 1) % MAX_SIZE == this.front;
        /// <summary>
        /// 清理队列元素
        /// </summary>
        public void Clear()=>this.front = this.rear = 0;

        public IEnumerator<T> GetEnumerator()
        {
            for(int i=this.front;i<this.rear;++i)
            {
                yield return this.data[i];
            }
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            for (int i = this.front; i < this.rear; ++i)
            {
                yield return this.data[i];
            }
        }
    }
}

链队列

/// <summary>
/// 队列
/// </summary>
namespace DataStruct.Queue
{
    /// <summary>
    /// 链队列
    /// </summary>
    /// <typeparam name="T">元素类型</typeparam>
    class LinkQueue<T>:IQueue<T>, IEnumerable<T>
    {
        /// <summary>
        /// 节点数
        /// </summary>
        private int count;
        /// <summary>
        /// 队头结点
        /// </summary>
        private Node<T> front;
        /// <summary>
        /// 队尾节点
        /// </summary>
        private Node<T> rear;
        /// <summary>
        /// 构造器
        /// </summary>
        public LinkQueue()
        {
            this.front = new Node<T>();
            this.rear = this.front;
        }
        /// <summary>
        /// 入队
        /// </summary>
        /// <param name="val">入队元素</param>
        public void Enter(T val)
        {
            Node<T> t = new Node<T>(val,rear.Next);
            this.rear=t;
            count++;
        }
        /// <summary>
        /// 出队
        /// </summary>
        /// <returns>返回出队元素</returns>
        public T Out()
        {
            if(IsEmpty())
                throw new IndexOutOfRangeException("队列满");
            Node<T> t = this.front.Next;
            this.front.Next = t.Next;
            if (this.rear == t)
                this.rear = this.front;
            count--;
            return t.Data;
        }
        /// <summary>
        /// 队列元素个数
        /// </summary>
        public int Count { get; }
        /// <summary>
        /// 判断队列空
        /// </summary>
        /// <returns>返回是否空</returns>
        public bool IsEmpty() => this.front == this.rear;
        /// <summary>
        /// 清理队列元素
        /// </summary>
        public void Clear() => this.front = this.rear;

        public IEnumerator<T> GetEnumerator()
        {
            Node<T> p = this.front;
            while(p.Next!=null)
            {
                p = p.Next;
                yield return p.Data;
            }
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            Node<T> p = this.front;
            while (p.Next != null)
            {
                p = p.Next;
                yield return p.Data;
            }
        }
    }
}

csharper
1 声望3 粉丝

曲终过尽松陵路,回首烟波十四桥。