数据结构:栈+队列

数据结构:栈+队列

一。栈(stack)

1.概念:

栈是一种特殊的线性表,只允许在固定的一端进行插入或删除操作

栈的出入原则是后进先出,可以把它理解成羊肉串,在最上面的羊肉是最后一个串上去的,也是第一个被吃到的

入栈:在栈顶进行导入 ,出栈:也在栈顶进行操作

2.栈的使用:

(1)push(E e): 将e入栈,并返回e

(2)pop( ):将栈顶元素出出去,并返回栈顶元素的数值

(3)peek( ):获取栈顶元素的数据

(4)size( ):获取栈的长度

(5)empty( ):获取栈是否为空

import java.util.Stack;
public class Test2 {
    public static void main(String[] args) {
        Stack<Integer> s=new Stack<>();
        s.push(11);
        s.push(22);
        s.push(33);
        s.push(44);
        System.out.println(s.size());
        s.pop();
        System.out.println(s.size());
        System.out.println(s.peek());
    }
}

3.栈的模拟实现:

栈的本质是使用数组,来将数据进行存储

import java.util.Arrays;
import java.util.Stack;

public class Test2 {
    int[] array;
    int size;
    public Test2(){
        array=new int[3];
    }
    public int push(int e){
        if(full()){
            array= Arrays.copyOf(array,2*array.length);
            array[size-1]=e;
            size++;
        }else{
            array[size-1]=e;
            size++;
        }
        return e;
    }
    public int peek(){
        int e=array[size-1];
        return e;
    }
    public int pop(){
        int e=peek();
        size--;
        return e;
    }
    public boolean full(){
        return size==array.length;
    }
    public boolean empty(){
        return 0==size;
    }
}

上述代码就是使用数组实现栈的代码,从上面的各个方法的实现能更好的理解stack中自带的方法

4. 栈的典型例题:逆波兰表达式

逆波兰表达式:

例:中序表达式:9+(3-1)3+8/2 后序表达式:931-3+82/+

后序表达式的由来就是把中序表达式所有运算加上括号,当括号内的运算有运算符时,把运算符放到括号后,然后把括号去掉,以此类推就成了上面这个例子中的后序表达式

用中序转后序表达式很难实现,但是后转中就可以使用栈进行实现

思路:先遍历数组,把数据放到栈中,当遇到运算符号时从栈中出两个元素,进行次运算符对应的运算,运算完将算出的值放到栈中,以此类推直到便利完整个数组,最后栈中只会留下一个数据,把数据提出就是中序表达式的答案

import java.util.Stack;

public class Test1 {
    public static int arr(String[] ret){//123+*3+
        Stack<Integer> hi=new Stack<>();
        for(int i=0;i<ret.length;i++){
            if(isnumber(ret[i])){//是数字
                hi.push(Integer.parseInt(ret[i]));
            }else{
                int a=hi.pop();
                int b=hi.pop();
                if(ret[i].equals("+")){
                    hi.push(a+b);
                }else if(ret[i].equals("-")){
                    hi.push(a-b);
                }else if(ret[i].equals("*")){
                    hi.push(a*b);
                }else if(ret[i].equals("/")){
                    hi.push(a/b);
                }
            }
        }
        return hi.pop();
    }
    public static boolean isnumber(String hehe){
        if(hehe.equals("+") || hehe.equals("-") || hehe.equals("*") || hehe.equals("/")){
            return false;
        }
        return true;
    }
    public static void main(String[] args) {
        String[] ret={"1","2","3","+","*","3","+"};
        System.out.println(arr(ret));
    }
}

二。队列(Queue)

1.概念:

一端进行插入,一端进行删除操作,它的工作原理与栈是相反的,队列是先进先出

队列就相当于一个管道,从一头进,再从另一头出,第一个进的元素就是第一个出的元素

进行插入操作的这一端叫做队尾

进行删除操作的这一端叫做队首

2.队列的使用:

在java中Queue是一个接口,本质上是通过链表来实现的

(1)offer(E e ):入队列,向队列中添加元素(这个方法的返回值是boolean类型)

(2)poll( ):出队首元素,并且返回队首元素的值

(3)peek( ):返回队首元素的值

(4)size( ):获取队列的长度

(5)isEmpty( ):获取队列是否为空

import java.util.LinkedList;
import java.util.Queue;
public class Test3 {
    public static void main(String[] args) {
        Queue<Integer> q=new LinkedList<>();
        q.offer(12);
        q.offer(22);
        q.offer(33);
        q.offer(44);
        System.out.println(q.size());
        q.poll();
        System.out.println(q.size());
        System.out.println(q.peek());
    }
}

3.队列的模拟实现:

本质上使用链表的形式进行实现

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

public class Test3 {
    static class ListNode{
        public int val;
        public ListNode next;
        public ListNode prev;
        public ListNode(int val){
            this.val=val;
        }
    }
    public ListNode head;
    public ListNode last;
    public boolean offer(int val){
        ListNode node=new ListNode(val);
        if(head==null){
            head=node;
            last=node;
            return true;
        }else{
            last.next=node;
            node.prev=last;
            last=last.next;
        }
        return false;
    }
    public int poll(){
        if(head==null){
            return -1;
        }else if(head.next==null){
            int curval=head.val;
            head=null;
            last=null;
            return curval;
        }else{
            int curval=head.val;
            head=head.next;
            head.prev=null;
            return curval;
        }
    }
    public int peek(){
        if(head==null){
            return -1;
        }
        return head.val;
    }
    public boolean empty(){
        return head==null;
    }
}

上述代码就是使用链表的方式实现队列的写法

4.循环队列:

本质上使用数组的方法进行循环队列的实现

中间的主要问题是数组长度,怎么判断这个循环队列是空的还是满的

这里使用预留一格的方法进行区分空和满的情况

如果队和尾是相同的,那么就判断成是空,如果(rear+1)%elem.length==front那么就判断成满

public class Test4 {
    public int[] elem;
    public int front;
    public int rear;
    public Test4(int k){
        elem=new int[k+1];
    }
    public boolean isEmpty(){
        return front==rear;
    }
    public boolean isFull(){
        return (rear+1)%elem.length==front;
    }
    public boolean enQueue(int value){
        if(isFull()){
            return false;
        }else{
            elem[rear]=value;
            rear=(rear+1)%elem.length;
            return true;
        }
    }
    public boolean deQueue(){
        if(isEmpty()){
            return false;
        }else{
            front=(front+1)%elem.length;
            return true;
        }
    }
    public int front(){
        if(isEmpty()){
            return -1;
        }
        return elem[front];
    }
    public int Rear(){
        if(isEmpty()){
            return -1;
        }
        int index=(rear==0)?elem.length-1:rear-1;
        return elem[index];
    }
}
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值