栈和队列算法有关的常见

栈和队列

逻辑概念
栈:数据先进后出
队列:数据先进先出
栈和队列的实际实现
双向链表实现
代码实现:

package class02;

import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

public class Code03_DoubleEndsQueueToStackAndQueue {

    public static class Node<T> {
        public T value;
        public Node<T> last;
        public Node<T> next;

        public Node(T data) {
            value = data;
        }
    }

    public static class DoubleEndsQueue<T> {
        public Node<T> head;
        public Node<T> tail;

        public void addFromHead(T value) {
            Node<T> cur = new Node<T>(value);
            if (head == null) {
                head = cur;
                tail = cur;
            } else {
                cur.next = head;
                head.last = cur;
                head = cur;
            }
        }

        public void addFromBottom(T value) {
            Node<T> cur = new Node<T>(value);
            if (head == null) {
                head = cur;
                tail = cur;
            } else {
                cur.last = tail;
                tail.next = cur;
                tail = cur;
            }
        }

        public T popFromHead() {
            if (head == null) {
                return null;
            }
            Node<T> cur = head;
            if (head == tail) {
                head = null;
                tail = null;
            } else {
                head = head.next;
                cur.next = null;
                head.last = null;
            }
            return cur.value;
        }

        public T popFromBottom() {
            if (head == null) {
                return null;
            }
            Node<T> cur = tail;
            if (head == tail) {
                head = null;
                tail = null;
            } else {
                tail = tail.last;
                tail.next = null;
                cur.last = null;
            }
            return cur.value;
        }

        public boolean isEmpty() {
            return head == null;
        }

    }

    public static class MyStack<T> {
        private DoubleEndsQueue<T> queue;

        public MyStack() {
            queue = new DoubleEndsQueue<T>();
        }

        public void push(T value) {
            queue.addFromHead(value);
        }

        public T pop() {
            return queue.popFromHead();
        }

        public boolean isEmpty() {
            return queue.isEmpty();
        }

    }

    public static class MyQueue<T> {
        private DoubleEndsQueue<T> queue;

        public MyQueue() {
            queue = new DoubleEndsQueue<T>();
        }

        public void push(T value) {
            queue.addFromHead(value);
        }

        public T poll() {
            return queue.popFromBottom();
        }

        public boolean isEmpty() {
            return queue.isEmpty();
        }

    }

    public static boolean isEqual(Integer o1, Integer o2) {
        if (o1 == null && o2 != null) {
            return false;
        }
        if (o1 != null && o2 == null) {
            return false;
        }
        if (o1 == null && o2 == null) {
            return true;
        }
        return o1.equals(o2);
    }

    public static void main(String[] args) {
        int oneTestDataNum = 100;
        int value = 10000;
        int testTimes = 100000;
        for (int i = 0; i < testTimes; i++) {
            MyStack<Integer> myStack = new MyStack<>();
            MyQueue<Integer> myQueue = new MyQueue<>();
            Stack<Integer> stack = new Stack<>();
            Queue<Integer> queue = new LinkedList<>();
            for (int j = 0; j < oneTestDataNum; j++) {
                int nums = (int) (Math.random() * value);
                if (stack.isEmpty()) {
                    myStack.push(nums);
                    stack.push(nums);
                } else {
                    if (Math.random() < 0.5) {
                        myStack.push(nums);
                        stack.push(nums);
                    } else {
                        if (!isEqual(myStack.pop(), stack.pop())) {
                            System.out.println("oops!");
                        }
                    }
                }
                int numq = (int) (Math.random() * value);
                if (stack.isEmpty()) {
                    myQueue.push(numq);
                    queue.offer(numq);
                } else {
                    if (Math.random() < 0.5) {
                        myQueue.push(numq);
                        queue.offer(numq);
                    } else {
                        if (!isEqual(myQueue.poll(), queue.poll())) {
                            System.out.println("oops!");
                        }
                    }
                }
            }
        }
        System.out.println("finish!");
    }

}

数组实现
数组实现栈:
分析:首先是给一个固定大小的数组的大小,首先定义一个变量index,初始没有值的时候为-1,增加值的时候arr[++index]=value;
代码实现:

package class02;
public class Code04_ArrtoStack {
    public static void push(int[]arr,int value,int index){
        arr[++index]=value;
    }
    public static int pop(int index){
        
        return index--;
    }
}

数组实现队列:
分析:由于队列的逻辑是先进先出的,所以我们要准备两个指针,一个指针指向队头,一个指向队尾,head和tail,开始时head=tail=-1;加入数时++tail,删除数时,++head,但是存在一个问题,当tail到达数组最大下标时,而head的小标不为0,此时就不能加入数据了,但此时数组里面还存在空间还能存储值,所以我们用limit来做限制
代码如下:

package class02;
public class Code04_RingArray {
    public static class MyQueue {
        public int[] arr;//数组
        public int pushindex;//队头加值
        public  int popindex;//队尾减值
        public  int size;//装的值
        public  int limit;//队列最大能装的数量
        public MyQueue(int i) {
            arr = new int[i];
            popindex=pushindex=0;
            size=0;
            limit=i;
        }
    public void push(int value){
       if(size == limit)
           throw new RuntimeException("空间满了,不能再加了");
        size++;
        arr[popindex] = value;
        if(size < limit - 1)
            popindex++;
        else 
            popindex = 0;
        }
    public int pop(){
         if(size == 0)
             throw new RuntimeException("没有值,不能往外拿值");
         int ans = arr[popindex];
         if(size<limit-1)
             popindex--;
         else 
             popindex = 0;
            return ans;
        }
    
    }
}

既然语言都有这些结构和api,为什么还要我们自己底层实现呢?
1)算法问题无关语言
2)语言提供的api是有限的,当我们需要实现新的功是api不能提供的时候,就需要自己去改写
3)任何软件工具的底层都是最基本的算法和数据结构,这是绕不过去的

栈和队列的常见面试题
实现一个特殊的栈,在基本功能的基础上,再实现返回栈中最小元素的功能
1.pop,push,getMin操作的时间复杂度都是O(1)
2 .设计的栈类型可以使用现成的栈结构
分析应该准备A,B两个栈,首先先往A栈压入值,其最小值就是压入栈的值,把该值也压入B栈,然后再把值压入A栈,比较A栈顶于B栈顶的大小,如果A栈顶的值小于B栈顶的值,蒋A栈顶的值也压入B栈,如果不大于,则B栈再压入原来B栈顶的值,依次这样,然后再弹栈的时候一次弹出A,B两个栈的栈顶,随便怎么弹,B的栈顶就是A栈的最小值,实现了O(1)。
1)如何用栈结构实现队列结构
分析:准备两个栈,把一个栈装满,然后把这个栈的东西导到另一个栈,从另外一个栈导出去。
2)如何用队列结构实现栈结构
分析:准备两个队列,把这个队列的东西只留一个值,剩下的值导进另外一个队列,然后把这个队列的值导出去,依次循环。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值