数据结构之栈和队列

一、栈

1、栈的概念

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

2、栈的使用
3、栈实例
(1)逆序打印链表

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

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

递归方式:

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

栈方式:

java 复制代码
Stack<Integer> stack=new Stack<>();
while(head!=null){
   stack.push(head.val);
   head=head.next;
}
while(!stack.empty()){
    System.out.print(stack.pop()+" ");
}
(2)括号匹配
java 复制代码
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)逆波兰表达式求值
java 复制代码
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)出栈入栈次序匹配
java 复制代码
 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)最小栈
java 复制代码
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,已空;

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

②保留一个位置

java 复制代码
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)用队列实现栈

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

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

java 复制代码
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)用栈实现队列

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

java 复制代码
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实现。

相关推荐
Crossoads42 分钟前
【数据结构】排序算法---快速排序
c语言·开发语言·数据结构·算法·排序算法
眰恦37444 分钟前
数据结构--第五章树与二叉树
数据结构·算法
未 顾1 小时前
JavaSE--集合总览02:单列集合Collection的体系之一:List
数据结构·list
wx200411021 小时前
Codeforces Round 973 (Div. 2) - D题
数据结构·c++·算法
Crossoads2 小时前
【数据结构】排序算法---基数排序
c语言·开发语言·数据结构·算法·排序算法
爱敲代码的憨仔2 小时前
第二讲 数据结构
数据结构·算法
问道飞鱼2 小时前
每日学习一个数据结构-布隆过滤器Bloom Filter
数据结构·学习·哈希算法
龙ze2 小时前
数据结构—(java)反射,枚举,lambda表达式
java·开发语言·数据结构
老薛爱吃大西瓜2 小时前
DAY15:链表实现学生信息管理系统
c语言·数据结构·学习·链表
眰恦3743 小时前
数据结构--第六章图
数据结构·算法