加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 电商 > 正文

自己动手实现java数据结构(四)双端队列

发布时间:2021-04-04 12:14:33 所属栏目:电商 来源:网络整理
导读:1.双端队列介绍 在介绍双端队列之前,我们需要先介绍队列的概念。和栈相对应,在许多算法设计中,需要一种" 先进先出(First Input First Output) "的数据结构,因而一种被称为" 队列(Queue) "的数据结构被抽象了出来(因为现实中的队列,就是先进先出的)。 队

  在remove操作中有多种可能的情况,由于思路相通,可以通过上面的举例说明帮助理解。

   /**
     * 双端队列 迭代器实现
     * private class Itr implements Iterator<E> {
        
         * 当前迭代下标 = head
         * 代表遍历从头部开始
         * */
        int currentIndex = ArrayDeque..head;

        
         * 目标终点下标 = tail
         * 代表遍历至尾部结束
         * int targetIndex = ArrayDeque.
         * 上一次返回的位置下标
         *  lastReturned;

        @Override
         hasNext() {
            :::当前迭代下标未到达终点,还存在下一个元素
            this.currentIndex != .targetIndex;
        }

        @Override
        @SuppressWarnings("unchecked")
         E next() {
            :::先暂存需要返回的元素
            E value = (E)ArrayDeque..currentIndex];

            :::最近一次返回元素下标 = 当前迭代下标
            this.lastReturned = .currentIndex;
            :::当前迭代下标 向后移动一位(需要取模)
            this.currentIndex = getMod(this.currentIndex + 1);

             value;
        }

        @Override
         remove() {
            if(this.lastReturned == -1){
                throw new IteratorStateErrorException("迭代器状态异常: 可能在一次迭代中进行了多次remove操作");
            }

            :::删除当前迭代下标的元素
            boolean deleteFromTail = delete(.currentIndex);
            :::如果从尾部进行收缩
            if(deleteFromTail){
                :::当前迭代下标前移一位
                this.currentIndex - 1:::为了防止用户在一次迭代(next调用)中多次使用remove方法,将lastReturned设置为-1
            this.lastReturned = -1;
        }

        
         * 删除队列内部数组特定下标处的元素
         * @param currentIndex 指定的下标
         *  true 被删除的元素靠近尾部
         *         false 被删除的元素靠近头部
         * boolean delete( currentIndex){
            Object[] elements = ArrayDeque..elements;
            int head = ArrayDeque..head;
            int tail = ArrayDeque..tail;

            :::当前下标 之前的元素个数
            int beforeCount = getMod(currentIndex - head);
            :::当前下标 之后的元素个数
            int afterCount = getMod(tail - currentIndex);

            :::判断哪一端的元素个数较少
            if(beforeCount < afterCount){
                :::距离头部元素较少,整体移动前半段元素

                :::判断头部下标 是否小于 当前下标
                if(head < currentIndex){
                    :::小于,正常状态  仅需要复制一批数据

                    :::将当前数组从"头部下标"开始,整体向右平移一位,移动的元素个数为"当前下标 之前的元素个数"
                    System.arraycopy(elements,head,elements,head+1,beforeCount);
                }else{
                    :::不小于,说明存在溢出环  需要复制两批数据

                    :::将数组从"0下标处"的元素整体向右平移一位,移动的元素个数为"从0到当前下标之间的元素个数"
                    System.arraycopy(elements,1:::将数组最尾部的数据设置到头部,防止被覆盖
                    elements[0] = elements[(elements.length-1)];
                    :::将数组尾部的数据整体向右平移一位
                    System.arraycopy(elements,head+1,(elements.length-head-1));
                }
                :::释放被删除元素的引用
                elements[currentIndex] = ;
                :::头部下标 向右移动一位
                ArrayDeque.this.head = getMod(ArrayDeque.);

                :::没有删除尾部元素 返回false
                false;
            }{
                :::距离尾部元素较少,整体移动后半段元素

                :::判断尾部下标 是否小于 当前下标
                if(currentIndex < tail){
                    :::将当前数组从"当前"开始,整体向左平移一位,移动的元素个数为"当前下标 之后的元素个数"
                    System.arraycopy(elements,currentIndex+1:::将数组从"当前下标处"的元素整体向左平移一位,移动的元素个数为"从当前下标到数组末尾的元素个数-1 ps:因为要去除掉被删除的元素"
                    System.arraycopy(elements,currentIndex+1,(elements.length-currentIndex-1));
                    :::将数组头部的元素设置到末尾
                    elements[elements.length-1] = elements[0];
                    :::将数组头部的数据整体向左平移一位,移动的元素个数为"从0到尾部下标之间的元素个数"
                    System.arraycopy(elements,1,0:::尾部下标 向左移动一位
                ArrayDeque.this.tail = getMod(ArrayDeque.);
:::删除了尾部元素 返回true true; } } }

3.2?基于链表的链式双端队列

  和向量不同,双向链表在头尾部进行插入、删除操作时,不需要额外的操作,效率极高。

  因此,我们可以使用之前已经封装好的的双向链表作为基础,轻松的实现一个链式结构的双端队列。限于篇幅,就不继续展开了,有兴趣的读者可以尝试自己完成这个任务。

4.双端队列性能

  空间效率:

    基于数组的双端队列:数组空间结构非常紧凑,效率很高。

    基于链表的双端队列:由于链式结构的节点存储了相关联的引用,空间效率比数组结构稍低。

  时间效率:

    对于双端队列常用的出队、入队操作,由于都是在头尾处进行操作,数组队列和链表队列的执行效率都非常高(时间复杂度(O(1)))。

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读