数组模拟栈
思路分析:
- 定义一个数组stack模拟栈
- 定义top指向栈顶 初始化为-1
- 入栈(push)操作:top++;stack[top]=data;
- 出栈(pop)操作:int value=stack[top];top–;return value;
代码实现:
package com.lylicoo.stack;
//数组模拟栈的基本操作的实现
public class ArrayStack {
private int maxSize;//栈的最大容量
private int[] stack;//定义一个数组 栈的数据存在数组中
private int top=-1;//指向栈顶
public ArrayStack(int maxSize) {
this.maxSize = maxSize;
stack=new int[maxSize];
}
//栈满
public boolean isFull(){
return top==maxSize-1;
}
//栈空
public boolean isEmpty(){
return top==-1;
}
//入栈
public void push(int data){
if (isFull()){
System.out.printf("栈满,无法入栈");
return;
}else{
top++;
stack[top]=data;
}
}
//出栈
public int pop(){
if (isEmpty()){
throw new RuntimeException("栈空");
}else{
int value=stack[top];
top--;
return value;
}
}
//显示栈
public void show(){
if (isEmpty()){
throw new RuntimeException("栈空");
}else{
for (int i=top;i>=0;i--){
System.out.printf("stack[%d]=%d\n",i,stack[i]);
}
}
}
}
测试:
package com.lylicoo.stack;
import java.util.Scanner;
public class ArrayStackDemo {
public static void main(String[] args) {
//测试
//创建ArrayStack的对象表示栈
ArrayStack stack = new ArrayStack(4);
String key="";
boolean loop=true;
Scanner sc = 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=sc.next();
switch(key){
case "show":
try {
stack.show();
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case "push":
System.out.println("请输入您要入栈的数据:");
int data=sc.nextInt();
stack.push(data);
break;
case "pop":
try{
int value=stack.pop();
System.out.println("出栈的数据是:"+value);
}catch (Exception e){
System.out.println(e.getMessage());
}
break;
case "exit":
loop=false;
break;
default:
break;
}
}
}
}
单链表模拟栈
思路分析:
- 因为是动态链表存储 故无需考虑栈满情况
- 创建节点类,创建一个top指针指向栈顶,初始化为null
- 入栈:将节点添加到链表表尾,并将top指针指向这个节点
- 出栈:将最后的节点出栈(将最后的节点从链表中删除),并将top指向最后节点的前一个节点
- 遍历:栈的遍历是先进后出,而链表是先进先出,所以可以通过反转链表再打印的方式实现栈的遍历。
代码实现:
package com.lylicoo.stack;
import com.lylicoo.linkedlist.singlelinkedlist.HeroNode;
//单链表模拟栈
public class SingleLinkedListStack {
private Node top = null;// 指向栈顶节点
//定义一个头节点
Node head = new Node(0);
//栈空
public boolean isEmpty() {
return top == null;
}
//入栈
public void push(Node node) {
//临时变量,保存头节点
Node temp = head;
while (true) {
if (temp.next == null) {
break;//已找到最后一个节点
}
temp = temp.next;
}//退出循环时说明已经找到最后一个节点
//将新节点添加到链表的最后
temp.next = node;
top = node;
}
//出栈 每次都将栈顶(top指向的)节点出栈
public Node pop() {
//临时变量,保存头节点
Node temp = head;
//出栈后 top需要向前移动 故借助辅助指针
Node tmp=top;
//top向前移动 故要先遍历找到top节点的前一个节点
while(true){
if (temp.next==top){
break;
}
temp=temp.next;
}//退出循环时说明已经找到top节点的前一个节点
temp.next=top.next;//删除top节点
//将top指针指向该节点
top=temp;
return tmp;
}
//显示栈 从栈顶开始显示 即 从链表表尾开始遍历链表
//采取反转链表后打印的方法
public void show() {
//判断链表是否为空
if (head.next==null){
System.out.println("链表为空");
return;
}
reverseList(head);//反转链表
Node temp=head.next;
while(true){
if (temp==null){
break;
}
System.out.println(temp);
temp=temp.next;
}
}
//反转链表
private void reverseList(Node head) {
if (head.next == null || head.next.next == null) {//链表为空或只有一个节点 不必反转
return;
}
Node resHead = new Node(0);
Node cur = head.next;//辅助变量
Node next = null;//用来保存cur的下一个节点 防止断链
while (cur != null) {
next = cur.next;
cur.next = resHead.next;//cur是被取下的节点 头插法
resHead.next = cur;//以上两行是头插法标配 画图更好理解!
cur = next;//cur后移 实现遍历
}
head.next = resHead.next;
}
}
//定义节点
class Node {
public int value;//值
public Node next;//指向下一节点
public Node(int value) {
this.value = value;
}
@Override
public String toString() {
return "Node{" +
"value=" + value +
", next=" + next +
'}';
}
}
测试:
package com.lylicoo.stack;
import java.util.Scanner;
public class SingleLinkedListStackDemo {
public static void main(String[] args) {
SingleLinkedListStack stack = new SingleLinkedListStack();
String key = "";
boolean loop = true;
Scanner sc = 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 = sc.next();
switch (key) {
case "show":
try {
stack.show();
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case "push":
System.out.println("请输入您要入栈的数据:");
int data = sc.nextInt();
Node node = new Node(data);
stack.push(node);
break;
case "pop":
try {
Node res = stack.pop();
System.out.println("出栈的节点是:" + res);
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case "exit":
sc.close();
loop = false;
break;
default:
break;
}
}
}
}