数据结构与算法绪论学习 Day5_队列

1  队列的概念和操作

1.1 队列的基本特征

  队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。它是一种先进先出(First In First Out)的线性表,简称FIFO。允许插入的一端称为队尾,允许删除的一端称为队头

1.2 队列的基本操作

  •   插入操作 ,在表尾插入元素 即入队
  •   删除操作 ,返回并删除表头元素 即出队

2  队列的基本实现

  队列属于线性表中的一种,那么就有顺序表和链表两种实现方式,但是不管哪种,都需要下面几个方法

Queue<T>()

创建一个空的队列

void Enqueue(T s)

往队列中添加一个新的元素

T Dequeue()

移除队列中最早添加的元素

bool IsEmpty()

队列是否为空

int Size()

队列中元素的个数


2.1 队列的顺序存储实现

using System;
using System.Text;

namespace 数据结构.线性表.队列
{
    public class QueueArr<T>
    {
        private T[] Nodes;
        private int index;
        private int head;
        private int tail;
        /// <summary>
        /// 初始化栈
        /// </summary>
        /// <param name="length"></param>
        public QueueArr (int length)
        {
            Nodes = new T[length];
            this.index = 0;
        }
        /// <summary>
        /// 入队操作
        /// </summary>
        /// <param name="node"></param>
        public void Enqueue (T node)
        {
            if (index == Nodes.Length)
            {
                ResizeLength(Nodes.Length * 2);
            }
            Nodes[tail] = node;
            tail++;
            index++;
            //StringBuilder sb = new StringBuilder();
            //foreach (var i in Nodes)
            //{
            //    sb.Append($"{i}、");
            //}
            //Console.WriteLine($"队列的长度是:{Size()},数组的长度是:{Nodes.Length},队列的内容是{sb}");
            Console.WriteLine($"队列的长度是:{Size()}");
        }
        /// <summary>
        /// 出队操作
        /// </summary>
        /// <returns></returns>
        public T Dequeue ()
        {
            if (index == 0)
            {
                return default;
            }
            T node = Nodes[head];
            Nodes[head] = default(T);
            head++;
            if (index > 0 && index == Nodes.Length / 4)
            {
                ResizeLength(Nodes.Length / 2);
            }
            index--;
            //StringBuilder sb = new StringBuilder();
            //foreach (var i in Nodes)
            //{
            //    sb.Append($"{i}、");
            //}
            //Console.WriteLine($"取出的元素是:{node},队列的长度是:{Size()},数组的长度是:{Nodes.Length},队列的内容是{sb}");
            Console.WriteLine($"取出的元素是:{node}");
            return node;
        }
        /// <summary>
        // 重构队列
        /// </summary>
        /// <param name="newLength"></param>
        public void ResizeLength (int newLength)
        {
            T[] newNodes = new T[newLength];
            if (newLength > Nodes.Length)
            {
                for (var i = 0; i < Nodes.Length; i++)
                {
                    newNodes[i] = Nodes[i];
                }
            }
            else
            {
                for (var i = 0; i < index; i++)
                {
                    newNodes[i] = Nodes[head++];
                }
                tail = newLength;
            }
            Nodes = newNodes;
            head = 0;
        }
        /// <summary>
        /// 获取栈的长度
        /// </summary>
        /// <returns></returns>
        public int Size ()
        {
            return this.index;
        }
        /// <summary>
        /// 判断
        /// </summary>
        /// <returns></returns>
        public bool IsEmpty () {
            return index == 0;
        }
    }
}

2.2 队列的链式存储实现

using System;
using 数据结构.链表;

namespace 数据结构.线性表.栈
{
    public class QueueALinkList<T>
    {
        int index;
        /// <summary>
        /// 头结点
        /// </summary>
        private Node<T> head;
        /// <summary>
        /// 尾节点
        /// </summary>
        private Node<T> tail;

        /// <summary>
        /// 初始化队列
        /// </summary>
        public QueueALinkList ()
        {
            head = null;
            tail = null;
        }
        /// <summary>
        /// 入队操作
        /// </summary>
        /// <param name="node"></param>
        public void Enqueue (T node)
        {
            Node<T> oldLastNode = tail;
            tail = new Node<T>(node);
            if (IsEmpty())
            {
                head = tail;
            }
            else
            {
                oldLastNode.Next = tail;
            }
            index++;
            Console.WriteLine($"入栈的元素是{node};栈的长度是:{Size()}");
        }
        /// <summary>
        /// 出队操作
        /// </summary>
        /// <returns></returns>
        public T Dequeue ()
        {
            var node = head;
            head = head.Next;
            index--;
            if (IsEmpty())
                tail = null;
            Console.WriteLine($"出栈的元素是{node.Item};栈的长度是:{Size()}");
            return node.Item;
        }
        /// <summary>
        /// 获取栈的长度
        /// </summary>
        /// <returns></returns>
        public int Size ()
        {
            return this.index;
        }
        /// <summary>
        /// 判断
        /// </summary>
        /// <returns></returns>
        public bool IsEmpty () {
            return index == 0;
        }
    }
}

3  C#中队列的实现

c#中也有队列的实现,即 命名空间System.Collections.Generic内的Queue,也提供了Dequeue,Enqueue方法,同时还提供了Peek方法(获取头部的元素但不删除它),没有反看源码,但是查资料C#内部是用的顺序存储的形式来实现队列的。貌似还是循环队列

队列的使用场景就多很多了,消息队列等等

原文地址:https://www.cnblogs.com/yuchenghao/p/13082150.html