08_栈
一、问题引入
请输入一个表达式
计算式:[7x2x2-5+1-5+3-3],点击计算(如图所示) 请问:计算机底层是如何运算得到结果的?注意不是简单的把算式列出运算,因为我们看这个算式7x2x2-5+1-5+3-3,但是计算机怎么理解这个算式的(对计算机而
言,它接收到的就是一个字符串),我们讨论的就是这个问题 --> 栈
二、栈的介绍
1)栈的英文为(stack);
2)栈是一个先入后出(FILO-First In Last Out)的有序列表;
3)栈(stack)是限制线性表中元素的插入和删除,只能在线性表的同一端进行的一种特殊线性表。允许插入和删除的一端,为变化的一端,称为栈顶(Top),另一端为固定的一端,称为栈底(Bottom);
4)根据栈的定义可知,最先放入栈中元素在栈底,最后放入的元素在栈顶,而删除元素刚好相反,最后放入的元素最先删除,最先放入的元素最后删除。
5)图解出栈与入栈的概念:
三、栈的应用场景
1)子程序的调用:在跳往子程序前,会先将下个指令的地址存到堆栈中,直到子程序执行完后再将地址取出,以回到原来的程序中。
2)处理递归调用:和子程序的调用类似,只是除了储存下一个指令的地址外,也将参数、区域变量等数据存入堆栈中。
3)表达式的转换[中缀表达式转后缀表达式]与求值(实际解决)。
4)二叉树的遍历。
5)图形的深度优先(depth-first)搜索法。
四、数组模拟栈
4.1 思路分析
1)使用数组来模拟栈
2)定义一个top来表示栈顶,初始化为-1
3)入栈的操作,当有数据加入到栈时,top++;stack[top]=data;
4)出栈的操作,int value = stack[top];top–;return value;
数组模拟栈思路分析图
4.2 代码实现
public class ArrayStackDemo {
public static void main(String
[] args
) {
ArrayStack arrayStack
= new ArrayStack(5);
arrayStack
.list();
arrayStack
.push(10);
arrayStack
.push(20);
arrayStack
.push(30);
arrayStack
.push(40);
arrayStack
.push(50);
arrayStack
.push(60);
arrayStack
.list();
int value
= arrayStack
.pop();
System
.out
.println(value
);
arrayStack
.list();
}
}
class ArrayStack{
private int maxSize
;
private int[] stack
;
private int top
= -1;
public ArrayStack(int maxSize
){
this.maxSize
= maxSize
;
stack
= new int[this.maxSize
];
}
public boolean isFull(){
return top
== maxSize
- 1;
}
public boolean isEmpty(){
return top
== -1;
}
public void push(int value
){
boolean flag
= isFull();
if (flag
){
System
.out
.println("该栈已满,无法插入数据!");
}else{
System
.out
.println("该栈未满,可以插入数据!");
top
++;
stack
[top
] = value
;
}
}
public int pop(){
boolean flag
= isEmpty();
if (flag
){
throw new RuntimeException("该栈已空,无法弹出数据!");
}else {
System
.out
.println("该栈未空,可以弹出数据!");
int value
= stack
[top
];
top
--;
return value
;
}
}
public void list(){
if (isEmpty()){
System
.out
.println("该栈已空,无法弹出数据!");
System
.out
.println("-------------------");
return;
}
for (int i
= top
; i
>= 0; i
--) {
System
.out
.println("stack["+ i
+ "] = " + stack
[i
] + " ");
}
System
.out
.println("-------------------");
}
}
五、链表模拟栈
5.1 代码实现
public class LinkedListStackDemo {
public static void main(String
[] args
) {
LinkedListStack linkedListStack
= new LinkedListStack(new SingleLinkedList());
linkedListStack
.showStack();
linkedListStack
.push(10);
linkedListStack
.push(20);
linkedListStack
.push(30);
linkedListStack
.showStack();
int value
= linkedListStack
.pop();
System
.out
.println(value
);
linkedListStack
.showStack();
}
}
class LinkedListStack{
private SingleLinkedList list
;
public LinkedListStack(SingleLinkedList list
) {
this.list
= list
;
}
public boolean isEmpty(){
return list
.getLength() == 0;
}
public void push(int value
){
Node node
= new Node(value
,null
);
list
.add(node
);
}
public int pop(){
boolean flag
= isEmpty();
if (flag
){
throw new RuntimeException("该栈已空,无法弹出数据!");
}else {
System
.out
.println("该栈未空,可以弹出数据!");
return list
.delete();
}
}
public void showStack(){
if (isEmpty()){
System
.out
.println("该栈为空栈!");
System
.out
.println("-------------------");
return;
}
list
.reversePrint(list
.getHead());
}
}
class SingleLinkedList{
private Node head
= new Node(null
,null
);
public Node
getHead() {
return head
;
}
public SingleLinkedList() {
}
public SingleLinkedList(Node head
) {
this.head
= head
;
}
public void add(Node node
){
Node temp
= head
;
while (true){
if (temp
.next
== null
){
break;
}
temp
= temp
.next
;
}
temp
.next
= node
;
}
public int delete(){
Node temp
= head
;
while (true){
if (temp
.next
.next
== null
){
break;
}
temp
= temp
.next
;
}
int value
= temp
.next
.value
;
temp
.next
= null
;
return value
;
}
public void showList(){
if (head
.next
== null
){
System
.out
.println("该链表为空链表!");
return;
}
Node temp
= head
.next
;
while (true){
if (temp
.next
== null
){
System
.out
.println(temp
);
break;
}
System
.out
.println(temp
);
temp
= temp
.next
;
}
}
public int getLength(){
int length
= 0;
if (head
.next
== null
){
return length
;
}
Node temp
= head
.next
;
while (true){
if (temp
.next
== null
){
break;
}
length
++;
temp
= temp
.next
;
}
return length
;
}
public void reversePrint(Node head
){
Stack
<Node> stack
= new Stack<>();
Node cur
= head
.next
;
while (cur
!= null
){
stack
.push(cur
);
cur
= cur
.next
;
}
while (stack
.size() > 0){
System
.out
.println(stack
.pop());
}
}
}
class Node{
public Integer value
;
public Node next
;
public Node(Integer value
, Node next
) {
this.value
= value
;
this.next
= next
;
}
@Override
public String
toString() {
return "Node{" +
"value=" + value
+
'}';
}
}