C#數據結構-隊列


隊列作為線性表的另一個數據結構,只允許在表的前端進行刪除操作,而在表的后端進行插入操作,和棧一樣,隊列是一種操作受限制的線性表。

先來看下用法:

            Queue queue = new Queue();
            queue.Enqueue(1);
            queue.Enqueue(2);
            queue.Enqueue(3);
            queue.Enqueue(4);
            foreach (var r in queue)
            {
                Console.Write($"data:{r} ");
            }
            Console.WriteLine();
            Console.WriteLine($"peek:{queue.Peek()}");
            queue.Dequeue();
            queue.Enqueue(5);
            queue.Enqueue(6);
            Console.WriteLine();

打印結果:

 

 

    public class MyQueue
    {
        /// <summary>
        /// 存儲棧結構
        /// </summary>
        public object[] content { get; set; }
        /// <summary>
        /// 隊列第一個節點
        /// </summary>
        public int head { get; set; }
        /// <summary>
        /// 對列最后一個節點
        /// </summary>
        public int tail { get; set; }
        /// <summary>
        /// 隊列長度
        /// </summary>
        public int size { get; set; }
        /// <summary>
        /// 增長因子 100 == 1.0
        /// </summary>
        public int growFactor { get; set; }
        /// <summary>
        /// 最小增加量
        /// </summary>
        private const int minimumGrow = 4;
        private const int _ShrinkThreshold = 32;
        /// <summary>
        /// 初始化
        /// </summary>
        public MyQueue()
            : this(32, (float)2.0)
        {
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="capacity">隊列長度</param>
        /// <param name="growFactor">增長因子</param>
        public MyQueue(int capacity, float _growFactor)
        {
            if (capacity < 0)
                throw new ArgumentOutOfRangeException("參數錯誤");
            if (!(_growFactor >= 1.0 && _growFactor <= 10.0))
                throw new ArgumentOutOfRangeException("增長因子不在范圍內");
            content = new Object[capacity];
            head = 0;
            tail = 0;
            size = 0;
            growFactor = (int)(_growFactor * 100);
        }
        /// <summary>
        /// 在隊列尾處添加節點
        /// </summary>
        /// <param name="obj"></param>
        public virtual void Enqueue(object obj)
        {
            if (size == content.Length)
            {
                //計算擴展后的隊列長度
                int newCapacity = (int)(content.Length * growFactor / 100);
                if (newCapacity < content.Length + newCapacity)
                {
                    newCapacity = content.Length + minimumGrow;
                }
                SetCapacity(newCapacity);
            }
            content[tail] = obj;
            tail = (tail + 1) % content.Length;
            size++;
        }
        /// <summary>
        /// 在隊列頭部出棧
        /// </summary>
        /// <returns></returns>
        public virtual Object Dequeue()
        {
            if (size == 0)
                throw new IndexOutOfRangeException("空隊列");
            object rem = content[head];
            content[head] = null;
            head = (head + 1) % content.Length;
            size--;
            return rem;
        }
        public virtual Object Peek()
        {
            if (size == 0)
                throw new IndexOutOfRangeException("空隊列");
            return content[head];
        }
        /// <summary>
        /// 擴展隊列
        /// </summary>
        /// <param name="capacity"></param>
        private void SetCapacity(int capacity)
        {
            object[] newArray = new object[capacity];
            if (size > 0)
            {
                if (head < tail)
                {
                    Array.Copy(content, head, newArray, 0, size);
                }
                else
                {
                    Array.Copy(content, head, newArray, 0, content.Length - head);
                    Array.Copy(content, 0, newArray, content.Length - head, head);
                }
            }
            content = newArray;
            head = 0;
            tail = (size == capacity) ? 0 : size;
        }
        public void ShowAll()
        {
            for (int i = head; i < size; i++)
            {
                Console.Write($"index:{i},data:{content[i]}    ");
            }
            Console.WriteLine("——————————————————————");
        }
    }

測試:

            MyQueue queue = new MyQueue();
            queue.Enqueue(1);
            queue.Enqueue(2);
            queue.Enqueue(3);
            queue.Enqueue(4);
            queue.ShowAll();
            Console.WriteLine($"peek:{queue.Peek()}");
            queue.Dequeue();
            queue.Enqueue(5);
            queue.Enqueue(6);
            queue.ShowAll();
            Console.ReadLine();

實現方式:

通過object對象數組,存儲隊列中的節點數據,另外定義兩個指針分別指向隊列的頭部節點以及尾部節點。

Enqueue入隊時,(如果隊列長度達到數組最大長度,則通過擴展數組(隊列長度 * 增長因子)來增加數組長度)通過在對尾附加節點來實現的。

Dequeue出隊時,通過頭指針后移實現出隊列。

另外未實現地方,為節省內存空間,數組中出隊后的空間也要加入到后續入隊時用到的閑置位置。

以上方法都是以虛方法的方式實現的,便於后續重寫(例如線程安全隊列)。

打印結果:

 

 


 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM