54.【数据结构--- 栈与队列】(一)

简介: 54.【数据结构--- 栈与队列】

(一)、栈

1.栈的定义(Stack):

栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。(先进后出)

2.栈链式储存结构的进栈出栈

链式栈的基本思路:是把添加的元素直接放在链表的第一个节点。出栈的时候也是直接把第一个节点进行出栈

设置链表:

public class Node {
        Node next;
        T item;
        public Node(T item, Node next) {
            this.item = item;
            this.next = next;
        }
    }

压栈:(压栈压的是头节点的下一个结点)

public void push(T t) {
        Node Insert = new Node(t, null);
        if (this.size == 0) {
            this.head.next = Insert;
        } else {
            //获取原先的第一个结点
            Node before = this.head.next;
            //开始进行链接
            this.head.next = Insert;
            Insert.next = before;
        }
        this.size++;
    }

出栈:(不用this.size-- 操作)

public T pop() {   //出栈的话不用--
        //获取第一个结点
        Node first = this.head.next;
        if (this.size == 1) {
            return first.item;
        } else {
            //获取第二个结点
            Node second = first.next;
            //开始断链
            this.head.next = second;
            //进行数量控制:
            return first.item;
        }
    }

类方法:

public class LinkeStack<T> {
    public class Node {
        Node next;
        T item;
        public Node(T item, Node next) {
            this.item = item;
            this.next = next;
        }
    }
    Node head;
    int size;
    public LinkeStack() {
        this.size = 0;
        this.head = new Node(null, null);
    }
    //获取个数
    public int getSize() {
        return this.size;
    }
    //进行压栈操作(实际上就是直接压入头节点的下一个结点)
    public void push(T t) {
        Node Insert = new Node(t, null);
        if (this.size == 0) {
            this.head.next = Insert;
        } else {
            //获取原先的第一个结点
            Node before = this.head.next;
            //开始进行链接
            this.head.next = Insert;
            Insert.next = before;
        }
        this.size++;
    }
    //进行出栈的操作:
    public T pop() {   //出栈的话不用--
        //获取第一个结点
        Node first = this.head.next;
        if (this.size == 1) {
            return first.item;
        } else {
            //获取第二个结点
            Node second = first.next;
            //开始断链
            this.head.next = second;
            //进行数量控制:
            return first.item;
        }
    }
}

3.栈顺序储存结构的出栈和进栈

类方法:(继承了顺序表的函数)

import java.util.ArrayList;
public class SquenceStack<T> extends SquenceLisr {
    public SquenceStack(int capacity){
        super(capacity);
    }
    //进行入栈
    public void push(T t){
        Insert(t);
    }
    //进行出栈
    public T pop(){
      return (T)remove(getLength()-1);
    }
}

主方法:

import java.sql.SQLOutput;
import java.util.*;
import java.awt.*;
import java.lang.Math;
public class hello  {
    public static void main(String []avgs) {
    SquenceStack<String> stack=new SquenceStack<>(10);
    stack.push("aa");
    stack.push("bb");
    stack.push("cc");
    stack.push("dd");
    for(int i=0;i<4;i++){
        System.out.println(stack.pop());
    }
    }
}

4.栈的实践操作(计算器)

4.1基础操作(两数相加)

import java.sql.SQLOutput;
import java.util.*;
import java.awt.*;
import java.lang.Math;
public class hello {
    public static void main(String[] avgs) {
        //设置表达式
      String express="7)8";
      //进行分步取解
        //获取数字1;
        char numStr1=express.charAt(0);
        //获取第二个数字:
        char numStr2=express.charAt(2);
        //获取中间的字符
        char operation=express.charAt(1);
        //进行字符串的转换
        int num1=Integer.parseInt(numStr1+"");  //只能转换字符串,所以这样做
        int num2=Integer.parseInt(numStr2+"");
        try {
           int reuult= Caluat(num1,num2,operation);
            System.out.println(reuult);
        } catch (Exception e) {
            System.out.println("输入的符号有错");
        }
    }
    public static int Caluat(int num1,int num2,char operation){
        switch(operation){
            case '+':
                return num1+num2;
            case '-':
                return num1-num2;
            case '*':
                return num1*num2;
            case '/':
                return num1/num2;
            default:
                return -0;
        }
    }
}
4.2进阶操作(10以内的,多数相加)

基本思路:创建两个栈、一个是数字栈、另一个是字符栈。然后通过对字符串的遍历得到对应的字符,然后通过判断字符,如果是逻辑表达式,那么就进入字符栈,如果是数字字符,那么就进入数字栈。然后再进行对最后进入的三个字符进行依次出栈,得到结果后,再进行入栈操作。直到最后字符栈为空就最后一次数字出栈。

import java.sql.SQLOutput;
import java.util.*;
import java.awt.*;
import java.lang.Math;
public class hello {
    public static void main(String[] avgs) {
        String express="1+2+3+5";
        //设置数字栈
      Stack<Integer> nums=new Stack<>();
      //设置字符栈
       Stack<Character> operation=new Stack();
       //进行压栈操作:
       for(int i=0;i<express.length();i++) {
           char ch=express.charAt(i);
           if (Judge(ch)){  //压入符号栈
               operation.push(ch);
           }else{  //压入数字栈
               nums.push(Integer.parseInt(ch+""));
           }
       }
       //进行出栈的操作
        while (!operation.empty()) {
            int num1=nums.pop();  //出栈数字1
            int num2=nums.pop();  //出栈数字2
            char operation1=operation.pop();  //出栈字符
            nums.push(Caluat(num1,num2, operation1));  //得出结果再入栈
        }
        System.out.println(nums.pop());
    }
    public static boolean Judge(char ch){
        return ch=='+'||ch=='-'||ch=='*'||ch=='/';
    }
    public static int Caluat(int num1,int num2,char operation){
        switch(operation){
            case '+':
                return num1+num2;
            case '-':
                return num1-num2;
            case '*':
                return num1*num2;
            case '/':
                return num1/num2;
            default:
                return -0;
        }
    }
}


相关文章
|
2天前
|
存储 C语言
数据结构基础详解(C语言): 栈与队列的详解附完整代码
栈是一种仅允许在一端进行插入和删除操作的线性表,常用于解决括号匹配、函数调用等问题。栈分为顺序栈和链栈,顺序栈使用数组存储,链栈基于单链表实现。栈的主要操作包括初始化、销毁、入栈、出栈等。栈的应用广泛,如表达式求值、递归等场景。栈的顺序存储结构由数组和栈顶指针构成,链栈则基于单链表的头插法实现。
|
3天前
|
Java
【数据结构】栈和队列的深度探索,从实现到应用详解
本文介绍了栈和队列这两种数据结构。栈是一种后进先出(LIFO)的数据结构,元素只能从栈顶进行插入和删除。栈的基本操作包括压栈、出栈、获取栈顶元素、判断是否为空及获取栈的大小。栈可以通过数组或链表实现,并可用于将递归转化为循环。队列则是一种先进先出(FIFO)的数据结构,元素只能从队尾插入,从队首移除。队列的基本操作包括入队、出队、获取队首元素、判断是否为空及获取队列大小。队列可通过双向链表或数组实现。此外,双端队列(Deque)支持两端插入和删除元素,提供了更丰富的操作。
10 0
【数据结构】栈和队列的深度探索,从实现到应用详解
|
8天前
|
Linux C++ Windows
栈对象返回的问题 RVO / NRVO
具名返回值优化((Name)Return Value Optimization,(N)RVO)是一种优化机制,在函数返回对象时,通过减少临时对象的构造、复制构造及析构调用次数来降低开销。在C++中,通过直接在返回位置构造对象并利用隐藏参数传递地址,可避免不必要的复制操作。然而,Windows和Linux上的RVO与NRVO实现有所不同,且接收栈对象的方式也会影响优化效果。
|
23天前
|
存储 安全 编译器
缓冲区溢出之栈溢出(Stack Overflow
【8月更文挑战第18天】
46 3
|
24天前
|
测试技术
【初阶数据结构篇】栈的实现(附源码)
在每一个方法的第一排都使用assert宏来判断ps是否为空(避免使用时传入空指针,后续解引用都会报错)。
|
10天前
crash —— 获取内核地址布局、页大小、以及栈布局
crash —— 获取内核地址布局、页大小、以及栈布局
|
10天前
|
存储 程序员 C语言
堆和栈之间有什么区别
【9月更文挑战第1天】堆和栈之间有什么区别
77 0
|
19天前
|
机器学习/深度学习 消息中间件 缓存
栈与队列的实现
栈与队列的实现
35 0
|
24天前
|
测试技术
【初阶数据结构篇】队列的实现(赋源码)
首先队列和栈一样,不能进行遍历和随机访问,必须将队头出数据才能访问下一个,这样遍历求个数是不规范的。
|
28天前
|
算法 C语言 C++
【practise】栈的压入和弹出序列
【practise】栈的压入和弹出序列