• 队列(循环队列的顺序实现)


    一、概述

    与栈相反,队列是先进先出(FIFO),后进后出的数据结构。插入的一端叫做队尾,而出去的一端则称为队头或队首。但是队列(Queue)有一种扩展形式,称为双端队列(Deque),即可以在两端都进行插入和删除的操作,看起来双端队列似乎更加使用,但在实际应用中却并不常见。同样的,队列也有两种实现形式,即顺序队列和链队列。链队列可以参考链栈,直接将出栈操作改成删除头节点即可,插入删除方便,适合栈和队列。

    顺序队列当然是数组实现,顺序队列的问题在于出队时前面空出的位置是否由后面的元素补充,如果不补充,那么会造成空间极度的浪费,如果补充,那么需要将每个元素都向前移,时间复杂度此时来到O(N),为了解决这个问题,循环队列应运而生,即将补充的元素放到前面由于出队而造成的空缺位置。这样就可以最大限度的利用已申请的空间。

    二、顺序实现循环队列

    数据域:

        private int Capacity;
        private int front;
        private int rear;
        private int [] data;
        static int DEFAULT_SIZE = 6;
        public Queue()
        {
            front = rear = 0;
            Capacity = DEFAULT_SIZE;
            data = new int [Capacity];
        }

    由于JAVA并不支持泛型数组,因此我们以int型的队列作为示例。

    这里简单描述一下循环队列的结构,一个空的循环队列如下图:

     当入队3个元素时变为:

     再出队1个元素

    接下来是求长度和判满空

        public int getSize()
        {
            return (rear - front + Capacity) % Capacity;
        }
    
        public boolean isEmpty()
        {
            return (rear == front);
        }
    
        public boolean isFull()
        {
            return ((rear + 1) % Capacity == front);
        }

    先说求元素个数(长度),从图中看起来好像直接返回rear-front即可,但是因为是循环队列,考虑下列情况:

     显然不能用简单的减法,必须将两种算法统一起来,因此(rear - front + Capacity) % Capacity正是起到这样的作用。

    再看判满,如果将元素完全装满,情况机会变为

    与空的情况一样都是两者重合,因此不能使用front==rear同时判断满和空,官方处理这种情况有两种办法,一是设置Flag进行标记,二是认为还剩一个空位时就认为队列已满。

    这里我们采用第二种策略。即下面的情况表示队列已满,请扩容再进行插入,不要完全占满。

    接下来分析入队出队

    出队比较简单,只需判断队列是否为空,如果不为空则将front向前移一位(注意front处于末尾怎么移)。

    入队则稍微比较复杂,首先判断是否满,如果不满,将新数据赋给当前rear所在的位置,然后rear将向后移一位(注意)。如果队列满了,则需进行扩容,乍一想,好像非常困难(我比较菜),后来仔细一想,你不需要再考虑旧队列的排列,直接相当于一次遍历并按顺序赋给新队列。以下为扩容代码:

        public void Enlarge()
        {
            int newCapacity = Capacity * 2 + 1;
            int [] newData = new int [newCapacity];
            for (int i = front, j = 0; i != rear; j++, i = (i + 1) % Capacity)
            {
                newData[j] = data[i];
            }
            front = 0;
            rear = getSize();
            data = newData;
            Capacity = newCapacity;
        }

    完整的数据结构代码及主函数测试代码可以查看我的github

  • 相关阅读:
    mysql常见的优化方法
    Mac 怎么通过自带终端连接linux服务器
    基于 appium 的 UI 自动化测试
    sourcetree在mac上的使用
    mac下git安装和使用
    mac 上更改环境变量
    Mac环境下svn的使用
    jira常用配置
    influxDB基本操作
    Collectd 和 InfluxDB 的部署和使用
  • 原文地址:https://www.cnblogs.com/lbrs/p/11725673.html
Copyright © 2020-2023  润新知