栈Stack和队列Queue

栈和队列

栈:是一种先进后出的数据结构

例题1:不可能的出栈顺序

一个栈的入栈序列是a,b,c,d,e则栈的不可能的输出序列是:(c)
A edcba       B decba        C dceab       D abcde

分析:

A,根据先进先出的原则,将abcde全部入栈,然后再出栈,即为A选项

B,d先出,说明abc已经在栈中了,然后d进栈,再出栈,e进栈,再出栈,然后cba一次出栈,即为B选项

C,a不可能比b先出栈

D,a进栈,再出栈,b进栈,再出栈,c进栈,再出栈,d进栈,再出栈,e进栈,再出栈

例题2:中缀表达式转为后缀表达式(逆波兰表达式)

手工方式:

  1. 按先加减后乘除的原则给表达式加括号
((a+(b*c))+(((d*e)+f)*g))
  1. 由内到外把每个括号里的表达式换成后缀
	abc*+de*f+g*+

例题3:利用顺序表实现栈

public class CreatStack {
    public int[] elem;
    public int usedSize;//记录当前下标
    public CreatStack() {
        this.elem = new int[5];
    }
    //压栈
    public void push(int val) {
        if (isFull()){
            System.out.println("栈满");
            return;
        }
            elem[usedSize]=val;
            usedSize++;
    }
//判满
    public boolean isFull() {
        if (usedSize==elem.length){
            return true;
        }
        return false;
    }
    //弹出栈顶元素
    public int pop() {
        if (empty()) {
//            System.out.println("栈空");
//            return -1;
            throw new RuntimeException("栈空");
        }
            int val = elem[usedSize - 1];
            usedSize = usedSize - 1;
             return val;
    }
//判空
    public boolean empty() {
        if (usedSize==0){
            return true;
        }
        return false;
    }
//只是获取栈顶元素 但是不删除
    public int peek() {
        if (empty()) {
            throw new RuntimeException("栈空");
        }
        return elem[usedSize - 1];
    }

    public static void main(String[] args) {
        CreatStack creatStack = new CreatStack();
        creatStack.push(2);
        int ret1=creatStack.pop();
        System.out.println(ret2);
    }
}

队列

队列Queue:先进先出的数据结构,尾进,头进

双端队列Deque:队头可进可出,队尾可进可出

1.1 队列

队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上 出数据,效率会比较低

public static void main(String[] args) {
        Queue<Integer> queue=new LinkedList<>();
        queue.offer(1);
        queue.add(2);
        int ret1=queue.poll();//出队【删除】
        int ret2=queue.peek();//获取队头
    }

在这里插入图片描述

例题1:用链表实现队列

public class TestQueue {
    public static class Node{
        public int val;
        public Node next;
        public Node(int val){
            this.val=val;
        }
    }
    public Node first;
    public Node last;
//入队(尾插法)
    public void offer(int val){
        Node node=new Node(val);
        if (this.first==null){
            this.first=node;
            this.last=node;
        }else {
            this.last.next=node;
            this.last=node;
        }
    }
    //出队(删除头结点)
    public int poll(){
        if(isEmpty()){
            throw new RuntimeException("队列为空");
        }else {
            int val=this.first.val;
            this.first=this.first.next;
            return val;
        }
    }
    public  boolean isEmpty(){
        return this.first==null;
    }
    public int peek(){
        if (isEmpty()){
            throw new RuntimeException("队列为空");
        }
        return this.first.val;
    }
}

1.2 循环队列

循环队列通常用数组来实现

分析循环队列实现过程:

step1:设首节点front和尾结点rear都指向0下标,当一组数进入队列时,放在0下标,新的rear=(rear+1)%lengh

在这里插入图片描述

step2:此时队满rear再一次遇见front,都指向0下标,因此无法判断何时为空为满

在这里插入图片描述

step3:解决办法:浪费一个空间来表示队满的情况

放值之前,先判断rear的下一个是不是front,如果是,就不能放值了,如下图:该队列已满,7下标虽然没放值,但是99不能放进去

在这里插入图片描述

step4:出队时,出一个值,front向后走一个,新的front=(front+1)%lengh,直到front和rear相遇,指向同一下标时,队列为空。

例题1:循环队列的实现

public class MyCircularQueue {
    private int[] elem;
    private int front;
    private int rear;
    public MyCircularQueue(int k) {
       this.elem=new int[k+1];//需要多给一个空间放判断满的rear
        }
//入队
        public boolean enQueue(int value) {
            if (isFull()){
                return false;
            }
            this.elem[this.rear]=value;
            this.rear=(this.rear+1)%this.elem.length;
            return true;
        }
//出队
        public boolean deQueue() {
            if (isEmpty()){
                return false;
            }
            this.front=(this.front+1)%this.elem.length;
            return true;
        }
  //显示队头
        public int Front() {
            if (isEmpty()){
                return -1;
            }
            return this.elem[this.front];
        }
//除了空之外,还要判断0下标为值空的情况
        public int Rear() {
            if (isEmpty()){
                return -1;
            }
            int index=-1;
            if (this.rear==0){
                index=elem.length-1;
            }else {
                index=this.rear-1;
            }
            return this.elem[index];
        }
  //判空,判满
        public boolean isEmpty() {
            return this.rear==this.front;
        }
        public boolean isFull() {
            return (this.rear+1)%this.elem.length==this.front;
        }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值