• 简单数据结构(二)队列


    队列

    顺序队列:用一片连续的存储空间来存储队列中的数据元素,这样的队列称为顺序队列(Sequence Queue)。用一维数组来存放顺序队列中的数据元素。队头位置设在数组下标为 0 的端,用 front 表示;队尾位置设在数组的另一端,用 rear 表示。 front 和 rear 随着插入和删除而变化。当队列为空时, front=rear=-1。
    图是顺序队列的两个指示器与队列中数据元素的关系图。

    image

    入队:进队列的元素 从队首开始排 慢慢排到队尾

    出队:出队列的元素 从队首开始出 一个个排下去

    顺序队列-(循环顺序队列):如果再有一个数据元素入队就会出现溢出。但事实上队列中并未满,还有空闲空间,把这种现象称为“假溢出”。这是由于队列“队尾入队头出”的操作原则造成的。解决假溢出的方法是将顺序队列看成是首尾相接的循环结构,头尾指示器的关系不变,这种队列叫循环顺序队列(Circular sequence Queue)。循环队列如图所示。


    image

    来自系统的队列:

    BCL 中的队列

    C#2.0 以下版本提供了非泛型的Queue类

    C#2.0 提供了泛型Queue<T>类
    方法
    1,Enqueue()入队(放在队首)
    2,Dequeue()出队(移除队首元素,并返回被移除的元素)
    3,Peek()取得队首的元素,不移除
    4,Clear()清空元素
    5,Count获取队列中元素的个数

    程序实现:

              //1.使用BCL中的队列
                Queue<int> queue = new Queue<int>();
    
                //入队
                  queue.Enqueue(23);//队首
                  queue.Enqueue(45);
                queue.Enqueue(67);
                queue.Enqueue(89);
                Console.Write("添加了23 45 67 89之后队列为:");
                foreach (int a in queue)
                {
                    Console.Write(a + " ");
                }
                Console.WriteLine();
                Console.WriteLine("添加了23 45 67 89之后队列的大小为:"+queue.Count);
    
                //出队(取得队首的数据,并删除)
                int i = queue.Dequeue();
                Console.WriteLine("取得队首的数据为:" + i);
                Console.WriteLine("出队之后队列的大小为:" + queue.Count);
                int j = queue.Peek();
                Console.WriteLine("Peek得到的结果是:" + j);
                Console.WriteLine("Peek之后队列的大小为:" + queue.Count);
                queue.Clear();
                Console.WriteLine("Clear之后队列的大小为:" + queue.Count);
    
                Console.ReadKey();


    结果:

    image


    自己实现队列:

    队列接口定义

    internal interface IQueue<T>
        {
            int Count { get; } //取得队列长度的属性
            int GetLength(); //求队列的长度
            bool IsEmpty(); //判断对列是否为空
            void Clear(); //清空队列
            void Enqueue(T item); //入队
            T Dequeue(); //出队
            T Peek(); //取队头元素
        }

    顺序队列的实现:

    class SeqQueue<T>:IQueue<T>
        {
            private T[] data;
            private int count;//表示当前有多少个元素
             private int front;//队首(队首元素索引减一)
            private int rear;//队尾(队尾元素索引)
    
            //构造函数
            public SeqQueue(int size)
            {
                data=new T[size];
                count = 0;
                front = -1;
                rear = -1;
            }
            //默认构造函数 
            public SeqQueue() : this(10)
            {
            }
            //返回队列内数量
            public int Count 
            {
                get { return count; }
            }
            //取得队列长度
            public int GetLength()
            {
                return count;
            }
            //判断队列是否唯为空
            public bool IsEmpty()
            {
                return count == 0;
            }
            //清除队列
            public void Clear()
            {
                count = 0;
                front = rear = -1;
            }
            //往队列里添加
            public void Enqueue(T item)
            {
                if (count==data.Length)
                {
                    Console.WriteLine("队列已满,不可以再添加新的数据");
                }
                else
                {
                    if (rear == data.Length-1)
                    {
                        data[0] = item;
                        rear = 0;
                    }
                    else
                    {
                        data[rear + 1] = item;
                        rear++;
                    }
                    count++;
                }
            }
            //移除队首元素 并返回该值
            public T Dequeue()
            {
                if (count > 0)
                {
                    T temp = data[front + 1];
                    front++;
                    count--;
                    return temp;
                }
                else
                {
                    Console.WriteLine("队列为空,无法取得队首的数据");
                    return default(T);
                }
            }
            //取得队首元素 不移除
            public T Peek()
            {
                T temp = data[front + 1];
                return temp;
            }
        }

    结果和之前是一样的,在这里就不贴出了。


    栈队列:队列的另外一种存储方式是链式存储,这样的队列称为链队列(Linked Queue)。链队列通常用单链表来表示,它的实现是单链表的简化。所以,链队列的结点的结构与单链表一样,如图所示。由于链队列的操作只是在一端进行,为了操作方便,把队头设在链表的头部,并且不需要头结点。

    image

    链队列结点类:

    class Node<T>
        {
            private T data;//数据域
            private Node<T> next;//引用域
    
            //构造方法
            public Node(T data)
            {
                this.data = data;
            }
            //数据域属性
            public T Data
            {
                get { return data; }
                set { data = value; }
            }
            //引用域属性
            public Node<T> Next
            {
                get { return next; }
                set { next = value; }
            }
        }

    栈队列的实现:

    class LinkQueue<T>:IQueue<T>
        {
            private Node<T> front;//头结点
            private Node<T> rear;//尾节点 
            private int count;//表示元素的个数
    
            public LinkQueue()
            {
                front = null;
                rear = null;
                count = 0;
            }
            public int Count 
            {
                get { return count; }
            }
            public int GetLength()
            {
                return count;
            }
            public bool IsEmpty()
            {
                return count == 0;
            }
            public void Clear()
            {
                front = null;
                rear = null;
                count = 0;
            }
            public void Enqueue(T item)
            {
                Node<T> newNode=new Node<T>(item);
                if (count == 0)
                {
                    front = newNode;
                    rear = newNode;
                    count = 1;
                }
                else
                {
                    rear.Next = newNode;
                    rear = newNode;
                    count++;
                }
            }
            public T Dequeue()
            {
                if (count == 0)
                {
                    Console.WriteLine("对列为空,无法出队");
                    return default(T);
                }
                else if (count == 1)
                {
                    T item = front.Data;
                    front = rear = null;
                    count = 0;
                    return item;
                }
                else
                {
                    T item = front.Data;
                    front = front.Next;
                    count--;
                    return item;
    
                }
            }
            public T Peek()
            {
                if (front != null)
                {
                    return front.Data;
                }
                else
                {
                    return default(T);
                }
            }
        }

    结果同上。

  • 相关阅读:
    OpenCV on Mac OSX: A step-by-step guide
    opencv打开摄像头获取视频程序
    使用find_if算法搜寻map的value
    c++如何理解map对象的value_type是pair类型
    关联容器执行器指定排序规则
    仿函数和函数配接器
    C++的异常处理
    back_insert_iterator和insert_iterator
    copy函数与ostream_iterator、reverse_iterator
    const_cast
  • 原文地址:https://www.cnblogs.com/moguwang/p/5251423.html
Copyright © 2020-2023  润新知