数据结构之栈和队列

一、栈

1、栈的概念

是一种线性表,具有后进先出的特点。只能在固定的一段进行数据的插入和删除,进行元素插入和删除的一端称为栈顶,另一端称为栈底。

2、栈的使用

3、栈实例
(1)逆序打印链表

eg:链表为1->2->3->4->5

逆序打印:5->4->3->2->1

递归方式:

void printList(ListNode head){
    if(null!=head){
       printList(head.next);
       System.out.print(head.val+" ");
    }
}

栈方式:

Stack<Integer> stack=new Stack<>();
while(head!=null){
   stack.push(head.val);
   head=head.next;
}
while(!stack.empty()){
    System.out.print(stack.pop()+" ");
}
(2)括号匹配

class Solution {
    public boolean isValid(String s) {
        int n=s.length();
        Stack<Character> stack=new Stack<>();
        for(int i=0;i<n;i++){
            char c=s.charAt(i);
            if(c=='('||c=='['||c=='{'){
                stack.push(c);
            }else{
                if(stack.empty()){
                    return false;
                }
                if(c==')'&&stack.peek()=='('||c==']'&&stack.peek()=='['||
                c=='}'&&stack.peek()=='{'){
                    stack.pop();
                }else{
                    return false;
                }
            }
        }
        return stack.empty();
    }
}
(3)逆波兰表达式求值
class Solution {
    public int evalRPN(String[] tokens) {
        int n=tokens.length;
        Stack<Integer> s=new Stack<>();
        for(int i=0;i<n;i++){
            String temp=tokens[i];
            if(!(temp.equals("+")||temp.equals("-")||temp.equals("*")||temp.equals("/"))){
                s.push(Integer.valueOf(temp));
            }else{
                int b=s.pop();
                int a=s.pop();
                if(temp.equals("+")){
                    s.push(a+b);
                }else if(temp.equals("-")){
                    s.push(a-b);
                }else if(temp.equals("*")){
                    s.push(a*b);
                }else{
                    s.push(a/b);
                }
            }
        }
        return s.pop();
    }
}
(4)出栈入栈次序匹配

 public boolean IsPopOrder (int[] pushV, int[] popV) {
        // write code here
        Stack<Integer> s=new Stack<>();
        int n=pushV.length;
        int j=0;
        for(int i=0;i<n;i++){
            s.push(pushV[i]);
            while(!s.empty()&&s.peek()==popV[j]){
                s.pop();
                j++;
            }
        }
        return j==n;
    }
(5)最小栈

class MinStack {
    Stack<Integer> s1;
    Stack<Integer> s2;
    public MinStack() {
        s1=new Stack<>();
        s2=new Stack<>();
    }
    
    public void push(int val) {
        s1.push(val);
        if(s2.empty()){
            s2.push(val);
        }else{
            if(s2.peek()>=val){
                s2.push(val);
            }
        }
    }
    
    public void pop() {
        int a=s1.pop();
        if(!s2.empty()&&s2.peek()==a){
            s2.pop();
        }
    }
    
    public int top() {
        return s1.peek();
    }
    
    public int getMin() {
        if(s2.empty()){
            return -1;
        }else{
            return s2.peek();
        }
    }
}
(6)栈、虚拟机栈、栈帧有什么区别?

栈:是一种线性表,具有后进先出的特点;

虚拟机栈:jvm划分的一块内存;

栈帧:调用方法的时候会在虚拟机当中给这个方法开辟一块内存。

二、队列

1、队列的概念

是一种线性表,具有先进先出的特点。只能在固定的一段进行数据的插入和删除,进行元素插入一端称为队尾,另一端称为队头。

2、队列的使用

注意:Queue是一个接口,在实例化对象时,使用LinkedList实例化对象,因为LinkedList实现了Queue接口。

3、队列实例
(1)循环队列

区分空与满

①记录长度标记

放入一个元素,长度+1;取出一个元素,长度-1;长度>队列最长长度,已满;长度<=0,已空;

该方法操作简单,就不再详细编写代码。

②保留一个位置

class MyCircularQueue {
    int[] elem;
    int front;
    int rear;
    public MyCircularQueue(int k) {
        elem=new int[k+1];
    }
    
    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;
        }else{
            return elem[front];
        }
    }
    
    public int Rear() {
        if(isEmpty()){
            return -1;
        }else{
            int index=(rear==0)?elem.length-1:rear-1;
            return elem[index];
        }
    }
    
    public boolean isEmpty() {
        return front==rear;
    }
    
    public boolean isFull() {
        return (rear+1)%elem.length==front;
    }
}
(2)用队列实现栈

队列:先进先出;栈:先进后出

两个队列一模一样:进出队列变换。

class MyStack {
    Queue<Integer> q1;
    Queue<Integer> q2;
    public MyStack() {
        q1=new LinkedList<Integer>();
        q2=new LinkedList<Integer>();
    }
    
    public void push(int x) {
        if(q1.isEmpty()){
            q2.offer(x);
        }else{
            q1.offer(x);
        }
    }
    
    public int pop() {
        if(empty()){
            return -1;
        }
        int temp=0;
        if(q1.isEmpty()){
            while(!q2.isEmpty()){
                temp=q2.poll();
                if(!q2.isEmpty()){
                   q1.offer(temp);
                }
            }
        }else{
            while(!q1.isEmpty()){
                temp=q1.poll();
                if(!q1.isEmpty()){
                    q2.offer(temp);
                }
            }
        }
        return temp;
    }
    
    public int top() {
        if(empty()){
            return -1;
        }
        int temp=0;
         if(q1.isEmpty()){
            while(!q2.isEmpty()){
                temp=q2.poll();
                q1.offer(temp);
            }
        }else{
            while(!q1.isEmpty()){
                temp=q1.poll();           
                q2.offer(temp);                
            }
        }
        return temp;
    }
    
    public boolean empty() {
        return q1.isEmpty()&&q2.isEmpty();
    }
}
(3)用栈实现队列

两个栈不一样,一个栈固定为入队列,一个栈固定为出队列。

class MyQueue {
    Stack<Integer> s1;
    Stack<Integer> s2;
    public MyQueue() {
        s1=new Stack<>();
        s2=new Stack<>();
    }
    public void push(int x) {
        s1.push(x);
    }
    
    public int pop() {
        if(empty()){
            return -1;
        }
        if(s2.empty()){
            while(!s1.empty()){
                s2.push(s1.pop());
            }
        }
        return s2.pop();
    }
    
    public int peek() {
        if(empty()){
            return -1;
        }
        if(s2.empty()){
            while(!s1.empty()){
                s2.push(s1.pop());
            }
        }
        return s2.peek();
    }
    
    public boolean empty() {
        return s1.empty()&&s2.empty();
    }
}
4、双端队列(Deque)

允许两端都可以进行入队和出队操作。Deque是一个接口,实例化对象使用LinkedList实现。

相关推荐

  1. 数据结构---队列

    2024-02-05 13:46:04       40 阅读
  2. 数据结构:队列

    2024-02-05 13:46:04       38 阅读
  3. 数据结构队列

    2024-02-05 13:46:04       22 阅读
  4. 数据结构队列

    2024-02-05 13:46:04       23 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-02-05 13:46:04       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-05 13:46:04       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-05 13:46:04       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-05 13:46:04       20 阅读

热门阅读

  1. Rust基础拾遗--看的不多只看一篇--基础

    2024-02-05 13:46:04       32 阅读
  2. 【Golang】自定义logrus日志保存为日志文件

    2024-02-05 13:46:04       29 阅读
  3. Python判断当前运行环境是否是jupyter notebook

    2024-02-05 13:46:04       22 阅读
  4. Linux 常用命令

    2024-02-05 13:46:04       31 阅读
  5. golang 创建unix socket http服务端

    2024-02-05 13:46:04       29 阅读
  6. Pandas 条件 关键字过滤

    2024-02-05 13:46:04       27 阅读
  7. SplashScreen使用

    2024-02-05 13:46:04       30 阅读
  8. 观察者模式(Observer)

    2024-02-05 13:46:04       26 阅读
  9. 过年手机推荐

    2024-02-05 13:46:04       27 阅读
  10. 前端学习之路(2) Vue3响应式模式设计原理

    2024-02-05 13:46:04       20 阅读
  11. Redis:bigkeys内存分析

    2024-02-05 13:46:04       28 阅读
  12. php 函数三

    2024-02-05 13:46:04       24 阅读
  13. 两次NAT

    两次NAT

    2024-02-05 13:46:04      28 阅读