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;
        }
    
    }
    
  • 相关阅读:
    form的get与post方式的区别(转)
    html中DIV+CSS与TABLE布局方式的区别及HTML5新加入的结构标签(转)
    HTML简介
    数据库设计 三范式
    索引与视图
    算法训练 连续正整数的和
    算法训练 寂寞的数
    算法训练 学做菜
    算法训练 猴子分苹果
    算法训练 A+B problem
  • 原文地址:https://www.cnblogs.com/dwwzone/p/12859253.html
Copyright © 2011-2022 走看看