4、栈
1、简介
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7jbH9WlS-1608815157298)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201216211223243.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tFUx46P3-1608815157304)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201216211401450.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bVWE6fzI-1608815157307)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201216211614669.png)]
总结:栈的特点 ====>
-
栈是一种特殊的线性表,插入和删除操作都在表的尾部进行。 表的尾部 <====> 栈顶
-
栈是后进先出的线性表。 打个比方:就像盘子一样,放的时候每次在上面,拿的时候也从上面开始拿。
-
栈分为:
-
顺序栈 ====> 顺序存储结构,通常用数组实现。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l35xrsJw-1608815157311)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201216213124225.png)]
-
链栈 ====> 链式存储结构,
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W4DsrHJG-1608815157317)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201216213041919.png)]
-
2、栈的抽象数据类型接口
/**
* @author Administrator
* 栈的抽象数据类型描述
*/
public interface IStack {
//1、将栈置空
public void clear();
//2、判断栈是否为空
public boolean isEmpty();
//3、返回栈的元素个数
public int length();
//4、返回栈顶元素
public Object peek();
//5、将数据元素x入栈
public void push(Object x);
//6、将栈顶元素出栈,并返回
public Object pop();
//7、输出栈中的所有元素
public void display();
}
3、顺序栈
/**
* @author Administrator 顺序栈:用数组实现
*/
public class SqStack {
// 存储空间
private Object[] stack;
// 指示栈顶元素的位置,指向栈顶元素存储位置的下一个存储单元位置
private int top;
// 栈的最大存储单元个数
private int max;
// 构造空栈,存储单元个数为最大
public SqStack(int max) {
super();
this.max = max;
// 构造栈
stack = new Object[max];
}
// 1、将栈置空: 栈顶为0即可
public void clear() {
top = 0;
}
// 2、判断栈是否为空
public boolean isEmpty() {
return top == 0;
}
// 3、返回栈的元素个数
public int length() {
return top;
}
// 4、返回栈顶元素
public Object peek() {
if(! isEmpty())
return stack[top -1];
else
return null;
}
// 5、将数据元素x入栈
public void push(Object x) {
//判断栈是否已满
if(top == max) {
System.out.println("栈满,不能插入!");
}
//否则,进行插入至栈顶
stack[top] = x;
top++;
}
// 6、将栈顶元素出栈,并返回
public Object pop() {
//判断栈是否为空
if(isEmpty()) {
return "空栈!";
}
top--;
//为啥先减再出栈??
return stack[top];
}
// 7、输出栈中的所有元素
public void display() {
for (int i = top - 1; i >= 0; i--) {
System.out.print(stack[i]+"<===");
}
}
}
测试:
public class SqStackTest {
public static void main(String[] args) {
SqStack sqStack = new SqStack(5);
// 1、判断栈是否为空
System.out.println(sqStack.isEmpty());
// 2、返回栈的元素个数
System.out.println(sqStack.length());
// 3、将数据元素x入栈
sqStack.push("徐凤年");
sqStack.push("青鸟");
sqStack.push("红麝");
sqStack.push("姜泥");
sqStack.push("洛阳");
// 4、判断栈是否为空
System.out.println(sqStack.isEmpty());
// 5、返回栈的元素个数
System.out.println(sqStack.length());
//6、再次入栈
//sqStack.push("陈芝豹");
//7、将栈顶元素出栈,并返回
System.out.println(sqStack.pop());
//8、输出栈中的所有元素
sqStack.display();
}
}
实例:实现括号匹配的语法检查
/**
* @author Administrator
* 利用顺序栈实现括号匹配
*/
public class CheckBrackets {
// 存储空间
private Object[] stack;
// 指示栈顶元素的位置,指向栈顶元素存储位置的下一个存储单元位置
private int top;
// 栈的最大存储单元个数
private int max;
// 构造空栈,存储单元个数为最大
public CheckBrackets(int max) {
super();
this.max = max;
// 构造栈
stack = new Object[max];
}
// 2、判断栈是否为空
public boolean isEmpty() {
return top == 0;
}
public void push(Object x) {
//判断栈是否已满
if(top == max) {
System.out.println("栈满,不能插入!");
}
//否则,进行插入至栈顶
stack[top] = x;
top++;
}
// 6、将栈顶元素出栈,并返回
public Object pop() {
//判断栈是否为空
if(isEmpty()) {
return "空栈!";
}
top--;
//为啥先减再出栈??
return stack[top];
}
//创建方法
public void isMatched(String str) {
//只要遍历出左括号,就入栈
for (int i = 0; i < str.length(); i++) {
//左括号入栈
if (str.charAt(i) == '(') {
push('(');
}
else if (str.charAt(i) == ')' && ! isEmpty()) {
pop();
}
else if (str.charAt(i) == ')' && isEmpty()) {
System.out.println("括号不匹配!");
return ;
}
}
if (isEmpty()) {
System.out.println("配对完毕,括号匹配!");
}
else {
System.out.println("括号不匹配!");
}
}
public static void main(String[] args) {
String string1 = "(a+b*(c+d))";
String string2 = "(a+b*(c+d)))";
CheckBrackets checkBrackets1 = new CheckBrackets(string1.length());
checkBrackets1.isMatched(string1);
CheckBrackets checkBrackets2 = new CheckBrackets(string2.length());
checkBrackets2.isMatched(string2);
}
}
4、链栈
引入结点类:
package linkedList;
/**
* @author Administrator
* 结点类
*/
public class Node {
//1、定义数据域,存放结点数据值
public Object data;
//2、定义指针域,存放后继结点
public Node next;
//无参构造函数
public Node() {
}
//有参构造函数
public Node(Object data, Node next) {
super();
this.data = data;
this.next = next;
}
public Node(Object data) {
super();
this.data = data;
}
}
链栈实现类:
package stack;
import linkedList.*;
/**
* @author Administrator
* 链栈
*/
public class LinkedStack {
//创建栈顶元素top
private Node top;
// 1、将栈置空: 栈顶为0即可
public void clear() {
top = null;
}
// 2、判断栈是否为空
public boolean isEmpty() {
return top == null;
}
// 3、返回栈的元素个数
public int length() {
Node p = top;
int length = 0;
while (p != null) {
p = p.next;
length++;
}
return length;
}
// 4、返回栈顶元素
public Object peek() {
if(! isEmpty())
return top.data;
else
return null;
}
// 5、将数据元素x入栈
public void push(Object x) {
Node s = new Node(x);
s.next = top;
top = s;
}
// 6、将栈顶元素出栈,并返回
public Object pop() {
if (isEmpty()) {
return null;
}
Node p = top;
top = top.next;
return p.data;
}
// 7、输出栈中的所有元素
public void display() {
Node p = top;
while (p != null) {
System.out.println(p.data+"===>");
p = p.next;
}
}
}
测试类:
package stack;
public class LinkedStackTest {
public static void main(String[] args) {
LinkedStack linkedStack = new LinkedStack();
System.out.println(linkedStack.isEmpty());
System.out.println(linkedStack.length());
linkedStack.push("徐凤年");
linkedStack.push("青鸟");
linkedStack.push("红麝");
linkedStack.push("姜泥");
System.out.println(linkedStack.isEmpty());
System.out.println(linkedStack.length());
System.out.println(linkedStack.pop());
System.out.println(linkedStack.peek());
}
实例:解决汉诺塔问题
package stack;
/**
* @author Administrator
* 编程汉诺塔问题
*/
public class Hanoi {
public static void main(String[] args) {
hanoi(1, 'x', 'y','z');
System.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *");
hanoi(3, 'x','y', 'z');
}
//解决汉诺塔方法
public static void hanoi(int n , char x , char y , char z) {
if(n == 1)
move(1,x,z);
else {
hanoi(n-1, x, z, y);
move(n, x, z);
hanoi(n-1, y, x, z);
}
}
//移动的方法
private static void move(int i, char x, char z) {
System.out.println("将圆盘==>"+i+"从塔座"+x+"移动到塔座"+z+" ");
}
}
t.println("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *");
hanoi(3, ‘x’,‘y’, ‘z’);
}
//解决汉诺塔方法
public static void hanoi(int n , char x , char y , char z) {
if(n == 1)
move(1,x,z);
else {
hanoi(n-1, x, z, y);
move(n, x, z);
hanoi(n-1, y, x, z);
}
}
//移动的方法
private static void move(int i, char x, char z) {
System.out.println("将圆盘==>"+i+"从塔座"+x+"移动到塔座"+z+" ");
}
}