zoukankan      html  css  js  c++  java
  • 队列和栈的问题

    一、用数组结构实现大小固定的栈

    【核心思想】

      栈结构是“后进先出”,有初始化栈、入栈、出栈、返回栈顶等功能,题目大意就是要求我们用数组实现栈的这些功能。

      初始化栈:给定一个初始大小,创建一个栈。定义一个变量 size ,初始化为 0,用来记录栈中的元素数量。

      入栈:如果 size 小于栈的大小,将要入栈的数放入数组的 size 位置上,size 加 1。否则报错。

      出栈:如果 size 大于 0,返回数组( size - 1 ) 位置上的数,size 减 1。否则报错。

      返回栈顶:如果 size 大于 0,返回数组(size - 1)位置上的数。否则报错。

    【代码实现】

    public class ArrayToStack {
        private int[] arr;
        private int size;
    
        /**
         * 初始化栈
         * @param initSize
         */
        public ArrayToStack(int initSize) {
            if (initSize < 0) {
                throw new IllegalArgumentException("The init size is less than 0!");
            }
            arr = new int[initSize];
            size = 0;
        }
    
        /**
         * 入栈
         * @param obj
         */
        public void push(int obj) {
            //size等于数组长度(栈的大小),说明栈已满,不能入栈
            if (size == arr.length) {
                throw new IndexOutOfBoundsException("The stack is full!");
            }
            arr[size++] = obj;
        }
    
        /**
         * 出栈
         * @return
         */
        public int pop() {
            //size等于0,说明栈空,不能出栈。
            if (size == 0) {
                throw new IndexOutOfBoundsException("The stack is empty!");
            }
            return arr[--size];
        }
    
        /**
         * 返回栈顶第一个元素
         * @return
         */
        public int peek() {
            //size等于0,说明栈空,所以没有栈顶。
            if (size == 0) {
                throw new IndexOutOfBoundsException("The stack is empty!");
            }
            return arr[size - 1];
        }
    
    }

    二、用数组结构实现大小固定的队列

    【核心思想】

    【实现代码】

    public class ArrayToQueue {
        private Integer[] arr;
        private Integer size;
        private Integer start;
        private Integer end;
    
        /**
         * 初始化队列
         * @param initSize
         */
        public ArrayToQueue(int initSize) {
            if (initSize < 0) {
                throw new IllegalArgumentException("The init size is less than 0");
            }
            arr = new Integer[initSize];
            size = 0;
            start = 0;
            end = 0;
        }
    
        /**
         * 入队
         * @param obj
         */
        public void push(int obj) {
            if (size == arr.length) {
                throw new ArrayIndexOutOfBoundsException("The queue is full");
            }
            size++;
            arr[end] = obj;
            end = end == arr.length - 1 ? 0 : end + 1;
        }
    
        /**
         * 出队
         * @return
         */
        public Integer pop() {
            if (size == 0) {
                throw new ArrayIndexOutOfBoundsException("The queue is empty");
            }
            size--;
            int tmp = start;
            start = start == arr.length - 1 ? 0 : start + 1;
            return arr[tmp];
        }
    
        /**
         * 返回队列的第一个数
         * @return
         */
        public Integer peek() {
            if (size == 0) {
                return null;
            }
            //如果size不等于0,返回start指向的数
            return arr[start];
        }
    } 

    三、如何仅用队列结构实现栈结构?

    【实现思路】

    【代码实现】

    /**
     * 仅用队列结构实现栈结构
     *
     * @author yi
     */
    public class QueueToStack {
        private Queue<Integer> data;
        private Queue<Integer> help;
    
        public QueueToStack() {
            this.data = new LinkedList<Integer>();
            this.help = new LinkedList<Integer>();
        }
    
        /**
         * 正常push添加进入queue
         * @param value
         */
        public void push(int value) {
            data.add(value);
        }
    
        /**
         * 在pop的时候,pop只留下一个元素,并把pop出来的元素加入到help队列中
         * @return
         */
        public int pop() {
            if (data.isEmpty()) {
                throw new RuntimeException("栈为空");
            }
            while (data.size() > 1) {
                //把data中的元素"剪切"到help队列,直到data只剩下一个元素
                help.add(data.poll());
            }
            //最后一个入队的元素
            int res = data.poll();
            //交换help和data的引用指向
            swap();
            return res;
        }
    
        /**
         * 返回栈顶的第一个元素
         * @return
         */
        public int peek() {
            if (data.isEmpty()) {
                throw new RuntimeException("栈为空");
            }
            while (data.size() > 1) {
                help.add(data.poll());
            }
            int res = data.poll();
            help.add(res);
            swap();
            return res;
        }
    
        public void swap() {
            Queue<Integer> temp = help;
            help = data;
            data = temp;
        }
    }

    四、如何仅用栈结构实现队列结构? 

     【实现思路】

      

    【代码实现】

    /**
     * 仅用栈结构实现队列结构
     *
     * @author yi
     */
    public class StackToQueue {
        private Stack<Integer> stackPush;
        private Stack<Integer> stackPop;
    
        public StackToQueue() {
            stackPush = new Stack<>();
            stackPop = new Stack<>();
        }
    
        /**
         * 入队
         * @param obj
         */
        public void push(int obj) {
            stackPush.push(obj);
        }
    
        /**
         * 出队
         * @return
         */
        public int poll() {
            if (stackPop.empty() && stackPush.empty()) {
                throw new RuntimeException("Queue is empty!");
            } else if (stackPop.empty()) {
                while (!stackPush.empty()) {
                    stackPop.push(stackPush.pop());
                }
            }
            return stackPop.pop();
        }
    
        /**
         * 返回队列的第一个数
         * @return
         */
        public int peek() {
            if (stackPop.empty() && stackPush.empty()) {
                throw new RuntimeException("Queue is empty!");
            } else if (stackPop.empty()) {
                while (!stackPush.empty()) {
                    stackPop.push(stackPush.pop());
                }
            }
            return stackPop.peek();
        }
    }

    五、栈的补充练习

      实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作。

    【要求】

      1.pop、push、getMin操作的时间复杂度都是O(1)。
      2.设计的栈类型可以使用现成的栈结构。

    【实现思路】

    【代码实现】

    public class MyStack {
        private Stack<Integer> stackData;
        private Stack<Integer> stackMin;
    
        public MyStack() {
            this.stackData = new Stack<>();
            this.stackMin = new Stack<>();
        }
    
        public void push(int newNum) {
            if (this.stackMin.isEmpty()) {
                this.stackMin.push(newNum);
            } else if (newNum < this.getMin()) {
                this.stackMin.push(newNum);
            } else {
                int newMin = this.stackMin.peek();
                this.stackMin.push(newMin);
            }
            this.stackData.push(newNum);
        }
    
        public int pop() {
            if (this.stackData.isEmpty()) {
                throw new RuntimeException("Your stack is empty");
            }
            this.stackMin.pop();
            return this.stackData.pop();
        }
    
        public int getMin() {
            if (this.stackMin.isEmpty()) {
                throw new RuntimeException("Your stack is empty.");
            }
            return this.stackMin.peek();
        }
    
        public static void main(String[] args) {
            MyStack stack = new MyStack();
            stack.push(3);
            System.out.println(stack.getMin());//3
            stack.push(5);
            System.out.println(stack.getMin());//3
            stack.push(1);
            System.out.println(stack.getMin());//1
            System.out.println(stack.pop());//1
            System.out.println(stack.getMin());//3
        }
    
    }

    六、队列的补充练习

    6.1 猫狗队列问题

    【题目】

      宠物、狗和猫的类如下: 

    public static class Pet {
        private String type;
    
        public Pet(String type) {
            this.type = type;
        }
    
        public String getPetType() {
            return this.type;
        }
    }
    
    public static class Dog extends Pet {
        public Dog() {
            super("dog");
        }
    }
    
    public static class Cat extends Pet {
        public Cat() {
            super("cat");
        }
    }

    【要求】

      实现一种狗猫队列的结构,要求如下:

    1. 用户可以调用add方法将cat类或dog类的 实例放入队列中;
    2. 用户可以调用pollAll方法,将队列中所有的实例按照进队列 的先后顺序依次弹出;
    3. 用户可以调用pollDog方法,将队列中dog类的实例按照 进队列的先后顺序依次弹出;
    4. 用户可以调用pollCat方法,将队列中cat类的实 例按照进队列的先后顺序依次弹出;
    5. 用户可以调用isEmpty方法,检查队列中是 否还有dog或cat的实例;
    6.  用户可以调用isDogEmpty方法,检查队列中是否有dog 类的实例; 用户可以调用isCatEmpty方法,检查队列中是否有cat类的实例

    【代码实现】

    public class DogCatQueue_Code {
        /**
         * 以下的Pet、Dog、Cat类是用户提供的基础类,不能修改
         */
        public static class Pet {
            private String type;
    
            public Pet(String type) {
                this.type = type;
            }
    
            public String getPetType() {
                return this.type;
            }
        }
    
        public static class Dog extends Pet {
            public Dog() {
                super("dog");
            }
        }
    
        public static class Cat extends Pet {
            public Cat() {
                super("cat");
            }
        }
    
        /**
         * 为了不修改原来的基础类,我们自定义一个PetEnterQueue类,这个类才是放入到猫狗队列中去的对象
         * 保留原来的属性pet,并且新增一个count属性,将不同实例盖上时间戳
         */
        public static class PetEnterQueue {
            private Pet pet;
            private long count;
    
            public PetEnterQueue(Pet pet, long count) {
                this.pet = pet;
                this.count = count;
            }
    
            public Pet getPet() {
                return this.pet;
            }
    
            public long getCount() {
                return this.count;
            }
    
            public String getEnterPetType() {
                return this.pet.getPetType();
            }
        }
    
        /**
         * 我们实现的队列就是PetEnterQueue类的实例
         * 首先有一个不断累加的数据项count用来表示实例进队列的时间(不分cat还是dog)
         * 同时有两个队列,一个只存放Dog,另一个只存放Cat。
         */
        public static class DogCatQueue {
            private Queue<PetEnterQueue> dogQ;
            private Queue<PetEnterQueue> catQ;
            private long count;
    
            public DogCatQueue() {
                this.dogQ = new LinkedList<>();
                this.catQ = new LinkedList<>();
                this.count = 0;
            }
    
            public void add(Pet pet) {
                //如果pet是dog类型
                if (pet.getPetType().equals("dog")) {
                    //在dog队列中添加信息:当前进入的是dog,并且当前数是count
                    this.dogQ.add(new PetEnterQueue(pet, this.count++));
                } else if (pet.getPetType().equals("cat")) {
                    this.catQ.add(new PetEnterQueue(pet, this.count++));
                } else {
                    throw new RuntimeException("err, not dog or cat");
                }
            }
    
            /**
             * 弹出整体最早的
             * @return
             */
            public Pet pollAll() {
                if (!this.dogQ.isEmpty() && !this.catQ.isEmpty()) {
                    //dog队列最早的dog最小,还是cat队列最早的cat最小
                    //注意这里使用的是peek而不是poll
                    //peek用于查询队列头部的元素;poll用于弹出队列中的头部元素
                    if (this.dogQ.peek().getCount() < this.catQ.peek().getCount()) {
                        return this.dogQ.poll().getPet();
                    } else {
                        return this.catQ.poll().getPet();
                    }
                } else if (!this.dogQ.isEmpty()) {
                    return this.dogQ.poll().getPet();
                } else if (!this.catQ.isEmpty()) {
                    return this.catQ.poll().getPet();
                } else {
                    throw new RuntimeException("err, queue is empty!");
                }
            }
    
            /**
             * 单独弹出dog
             * @return
             */
            public Dog pollDog() {
                if (!this.isDogQueueEmpty()) {
                    return (Dog) this.dogQ.poll().getPet();
                } else {
                    throw new RuntimeException("Dog queue is empty!");
                }
            }
    
            /**
             * 单独弹出cat
             * @return
             */
            public Cat pollCat() {
                if (!this.isCatQueueEmpty()) {
                    return (Cat) this.catQ.poll().getPet();
                } else {
                    throw new RuntimeException("Cat queue is empty!");
                }
            }
    
            public boolean isDogQueueEmpty() {
                return this.dogQ.isEmpty();
            }
    
            public boolean isCatQueueEmpty() {
                return this.catQ.isEmpty();
            }
        }
    
        public static void main(String[] args) {
            DogCatQueue test = new DogCatQueue();
    
            Pet dog1 = new Dog();
            Pet cat1 = new Cat();
            Pet dog2 = new Dog();
            Pet cat2 = new Cat();
            Pet dog3 = new Dog();
            Pet cat3 = new Cat();
    
            test.add(dog1);
            test.add(cat1);
            test.add(dog2);
            test.add(cat2);
            test.add(dog3);
            test.add(cat3);
    
            test.add(dog1);
            test.add(cat1);
            test.add(dog2);
            test.add(cat2);
            test.add(dog3);
            test.add(cat3);
    
            test.add(dog1);
            test.add(cat1);
            test.add(dog2);
            test.add(cat2);
            test.add(dog3);
            test.add(cat3);
    
            while (!test.isDogQueueEmpty()) {
                System.out.println(test.pollDog().getPetType());
            }
            while (!test.isCatQueueEmpty()) {
                System.out.println(test.pollCat().getPetType());
            }
        }
    }

    参考:https://blog.csdn.net/LYN9822/article/details/86530165

  • 相关阅读:
    正则表达式(一个字符串翻转的例子)(http://www.cnblogs.com/hai98)
    电话号码正则表达式
    用哪种方法判断字符串为空更快速
    SQL内数据类型
    正则表达式基础(http://www.cnblogs.com/hai98)
    随机生成数
    C#源码 备份和恢复数据库
    ajax技术制作得在线歌词搜索功能
    ReadyGo新闻管理系统 1.5版 无任何使用限制
    最新完成的asp.net 2.0网站
  • 原文地址:https://www.cnblogs.com/yft-javaNotes/p/10719905.html
Copyright © 2011-2022 走看看