zoukankan      html  css  js  c++  java
  • Deque--双向队列,支持同时在两端添加或删除元素--基于双向链表或动态数组的实现

    支持以下API
    isEmpty() 判断队列是否为空
    size() 节点数量
    pushLeft() 左端插入节点
    pushRight() 右端插入节点
    popLeft() 左端删除节点
    popRight() 右端删除节点

    代码

    import java.util.Iterator;
    
    /**
     * @author 鯉伴MAY
     * @param <Item>
     */
    public class Deque <Item> implements Iterable<Item>{
        public Deque() {}
    
        private class DequeNode {
            Item item;
            DequeNode pre;
            DequeNode next;
        }
        private DequeNode first;
        private DequeNode last;
        private int N;
        public boolean isEmpty(){
            return first == null;
        }
        public  int size() {
            return N;
        }
    
        //创建新的节点
        private DequeNode newNode(Item item) {
            DequeNode temp = new DequeNode();
            temp.item = item;
            return  temp;
        }
    
        //从左端插入节点
        public void pushLeft(Item item) {
            DequeNode xNode = newNode(item);
            if(isEmpty()) {
                first = xNode;
                last = xNode;
            }else {
                xNode.next = first;
                first.pre = xNode;
                first = xNode;
            }
            N++;
        }
    
        //从右端插入节点
        public void pushRight(Item item) {
            DequeNode xNode = newNode(item);
            if(isEmpty()) {
                first = xNode;
                last = xNode;
            }else {
                last.next = xNode;
                xNode.pre = last;
                last = xNode;
            }
            N++;
        }
    
        //从左端弹出节点
        public Item popLeft() {
            if(isEmpty()){
                System.out.println("栈已空");
                return null;
            }
            DequeNode temp = first;
            if(size() == 1) {
                first = null;
                last = null;
            }else {
                first = first.next;
                first.pre = null;
                temp.next = null;
            }
            N--;
            return temp.item;
        }
    
        //从右端弹出节点
        public Item popRight() {
            if(isEmpty()) {
                System.out.println("队列已空");
                return null;
            }
            DequeNode temp = last;
            if(size() == 1) {
                first = null;
                last = null;
            }else {
                last = last.pre;
                last.next = null;
                temp.pre = null;
            }
            N--;
            return  temp.item;
        }
    
    
        public void printStack() {
            DequeNode temp = first;
            while(temp != null) {
                System.out.println(temp.item);
                temp = temp.next;
            }
        }
    
        @Override
        public Iterator<Item> iterator() {
            return new LIterator();
        }
        private class LIterator implements  Iterator<Item>{
            private DequeNode current = first;
            @Override
            public boolean hasNext() {
                return current != null;
            }
            @Override
            public Item next() {
                Item item = current.item;
                current = current.next;
                return item;
            }
        }
    }
    

    基于动态数组分配的实现

    在实现过程中,我们检测队列的大小是否小于数组的四分之一,如果小于,则将长度减半,此时数组状态约为半满,在下次改变数组大小之前仍可以多次push和pop,同时,检测队列是否装满数组,如果装满,则将数组长度加倍。这样,栈不会溢出,且使用率也永远高于四分之一。

    public class ResizingArrayDeque<Item> {
        private int cap = 5;//数组的容量初始值设为5
        private Item[] array;
        private int N;
        public ResizingArrayDeque() {
            array = (Item[]) new Object[cap];
        }
    
        private void resize(int max){
            Item[] temp = (Item[]) new Object[max];
            for (int i = 0; i < N; i++) {
                temp[i] = array[i];
            }
            array = temp;
        }
    
        public boolean isEmpty() {
            return  N==0;
        }
    
        public int size(){
            return  N;
        }
    
        public void pushLeft(Item item) {
            if(N == array.length)
                resize(2*array.length);
            //往后循环移位,空出第一位
            for (int i = N; i >0 ; i--) {
                array[i]=array[i-1];
            }
            array[0] = item;
            N++;
        }
    
        public void pushRight(Item item) {
            if(N == array.length)
                resize(2*array.length);
            array[N++] = item;
        }
    
        public Item popLeft() {
            if(N==0){
                System.out.println("队列已空");
                return null;
            }
            //弹出第一位,往前递补
            Item temp = array[0];
            for(int i=0;i<N-1;i++) {
                array[i] = array[i+1];
            }
            array[N-1] = null;
            N--;
            if(N>0 && N == array.length/4)
                resize(array.length/2);
            return temp;
        }
    
        public Item popRight() {
            if(N==0){
                System.out.println("队列已空");
                return null;
            }
            Item temp = array[--N];
            array[N] = null;//置空,避免对象游离
            if(N>0 && N == array.length/4)
                resize(array.length/2);
            return temp;
        }
    
    }
    
  • 相关阅读:
    多个类定义attr属性重复的问题:Attribute "xxx" has already been defined
    好用的批量改名工具——文件批量改名工具V2.0 绿色版
    得到ImageView中drawable显示的区域的计算方法
    得到view坐标的各种方法
    实现类似于QQ空间相册的点击图片放大,再点后缩小回原来位置
    Material Designer的低版本兼容实现(五)—— ActivityOptionsCompat
    Android 自带图标库 android.R.drawable
    解决 Attempting to destroy the window while drawing!
    解决Using 1.7 requires compiling with Android 4.4 (KitKat); currently using API 4
    Material Designer的低版本兼容实现(四)—— ToolBar
  • 原文地址:https://www.cnblogs.com/dwwzone/p/12859253.html
Copyright © 2011-2022 走看看