JAVA数据结构——数组,单链表(头插法,尾插法)模拟栈
前言:
首先让我们了解一下什么是栈?
1.栈的名称为(stack)
2.栈是先入后出(FILO-FirstLast Out)的有序列表
3.栈是线性表中元素的插入和删除,只能在线性表中的同一端进行一种特殊的线性表,允许插入删除 的一端,为变化的一端,称为栈顶(Top),另一端为固定的一端,称为栈底(Bottom)。
4.根据栈的定义可以知道,最先放入栈中元素在栈底,最后放入的元素在栈顶,而删除元素刚好相反,最后放入的元素最先删除,最先放入的元素后删除。
栈的应用场景
1.子程序的调用:在跳往子程序前,会先将下一个指令的地址存到栈中,直到子程序执行完之后再将地址取出,一起回到原来的程序中。
2.表达式的转换【中缀表达式转后缀表达式】与求值(实际解决)
3.二叉树的遍历
4.图形的深度优先(depth–first)搜索法
栈的快速入门:
1)用数组模拟栈的使用,由于栈是一种有序列表,当然可以使用数组结构来存储栈的数据内容,下面我们就用数组模拟栈的出栈,和入栈等操作。
2)实现思路分析,并画出示意图
代码:
先创建节点实体类
// 首先我们需要写出一个实体类也就是代表着每一个节点
class LinkedStack{
private int no;
private LinkedStack next;
public LinkedStack(int no) {
this.no = no;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public LinkedStack getNext() {
return next;
}
public void setNext(LinkedStack next) {
this.next = next;
}
@Override
public String toString() {
return "LinkedStack{" +
"no=" + no +
'}';
}
}
接下来是数组模拟栈的代码:
// 定义一个ArrayStack表示栈
class ArrayStack{
private int maxSize;// 栈的大小
private int[] stack;// 数组,数组模拟栈,数据就放在该数组
private int top = -1;// 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){
// 先判断栈是否满了?
if (isFull()){
System.out.println("栈满");
return;
}
top ++ ;
stack[top] = value;
}
// 出栈,pop,将栈顶的数据返回
public int pop(){
// 先判断栈是否空?
if (isEmpty()){
// 抛出异常
throw new RuntimeException("该栈已经为空,没有数据");
}
int value = stack[top];
top--;
return value;
}
// 显示栈的情况,遍历栈
// 遍历时需要从栈顶返回数据
public void List(){
if(isEmpty()){
System.out.println("栈空没有数据");
return;
}
for(int i = top ;i >= 0; i-- ){
System.out.printf("stack[%d]=%d\n",i,stack[i]);
}
}
}
测试代码和结果:
代码
ArrayStack arrayStack = new ArrayStack(4);
String key = "" ;
boolean loop = true;// 控制是否退出菜单
Scanner scanner = new Scanner(System.in);
while(loop){
System.out.println("show:显示栈");
System.out.println("exit:退出程序");
System.out.println("push:添加数据到栈");
System.out.println("pop:表示从栈取出数据");
System.out.println("请输入你的选择:");
key =scanner.next();
switch (key){
case "show":
arrayStack.List();
break;
case "push":
System.out.println("请输入一个数:");
int value = scanner.nextInt();
arrayStack.push(value);
break;
case "pop":
try{
int res = arrayStack.pop();
System.out.println("出栈的数据是"+res);
}catch (Exception e){
System.out.println(e.getMessage());
}
break;
case "exit":
scanner.close();
loop = false;
break;
default:
break;
}
}
结果:
4)将程序改成使用链表来模拟栈。
头插法:
// 头插法来模拟栈的原理
class LinkedListStack{
private LinkedStack top = new LinkedStack(-1);
// 判断栈是否为空
public boolean isEmpty(){
return top.getNo() == -1;
}
// 入栈
public void push(LinkedStack ls){
LinkedStack temp = top;
if (top.getNext() == null ){
// 证明是第一个
top.setNext(ls);
return;
}
LinkedStack cur = top.getNext();
top.setNext(ls);
ls.setNext(cur);
}
// 出栈
public void pop(){
System.out.println("出栈的节点为:"+top.getNext().getNo());
top = top.getNext();
}
// 遍历
public void show(){
if (top.getNext() == null ){
System.out.println("栈空");
return;
}
LinkedStack temp = top;
while(temp.getNext() != null){
System.out.println("节点为"+temp.getNext().getNo());
temp = temp.getNext();
}
}
}
测试代码和结果:
LinkedStack p1 = new LinkedStack(3);
LinkedStack p2 = new LinkedStack(1);
LinkedStack p3 = new LinkedStack(5);
LinkedListStack a1 = new LinkedListStack();
a1.push(p1);
a1.push(p2);
a1.push(p3);
a1.show();
a1.pop();
a1.pop();
a1.pop();
a1.show();
尾插法
// 尾插法来模拟栈
class LinkedListStack2 {
private LinkedStack head = new LinkedStack(-1);
LinkedStack top = head;
// 判断栈是否为空
public boolean isEmpty() {
return head.getNext() == null;
}
// push
public void push(LinkedStack ls) {
if (head.getNext() == null) {
// 第一个插进来的
head.setNext(ls);
top = ls;
return;
}
top.setNext(ls);
top = ls;
}
// pop
public void pop(){
LinkedStack temp = head;
while(true){
if (temp.getNext().getNext() == null){
// 证明找到了最后一个的前一个
System.out.println("取出的节点是:"+temp.getNext().getNo());
// 然后我们去除节点
temp.setNext(null);
// 最后我们退出
return;
}
temp = temp.getNext();
}
}
// show
public void List(){
if (head.getNext() == null){
System.out.println("栈空啦");
return;
}
LinkedStack temp = head.getNext();
while(true){
if (temp.getNext() != null){
System.out.println(temp);
temp = temp.getNext();
}else if (temp.getNext() == null){
System.out.println(temp);
return;
}
}
}
测试结果和代码
LinkedStack p1 = new LinkedStack(3);
LinkedStack p2 = new LinkedStack(1);
LinkedStack p3 = new LinkedStack(5);
LinkedListStack2 a2 = new LinkedListStack2();
a2.push(p1);
a2.push(p2);
a2.push(p3);
a2.List();
a2.pop();
a2.pop();
a2.pop();
a2.List();