写了一下用单链表模拟栈,出了几个问题:
1.push(入栈)时只能传进去第一个数据,其他数据无法入栈
2.入栈问题解决后,显示栈中元素时出错,原因是我使用的临时变量指针初始化时可能会出现的空指针错误。
3.显示元素时一次只能显示2个数据(数据全部入栈了),出栈一个,就再往下显示一个。这个问题还未解决,先把下一节课学了再考虑考虑吧。
4.显示元素的时候,最开始不是想用链表逆序的方法,而是想通过对单链表进行一次次的遍历,每次遍历都比上一次少了最后一个节点,但是这个方法后来行不通,就改用逆序的方法了
参考了这篇文章:【数据结构】如何用单链表实现栈?_黄金鸡米花的博客-优快云博客_单链表实现栈
//一改
public void show() {
if (first==null) {
System.out.println("栈空");
return;
}
int i=1;
if(first.next==null) {
System.out.println("stack"+i+"="+first.no);
return;
}
i=2;
//遍历链表,获取总元素个数
StackNodes temp1=first.next;
StackNodes temp=first;
while(temp1.next != null) {
temp = temp1;
temp1 = temp1.next;
i++;
}
System.out.println("栈中元素总数:"+i);
//应该按照从栈顶往栈底的顺序
int n=0;
int j;
while(first.next!=null) {//至少有两个
temp1=first.next;
temp2=first;
for(j=1;j<i-n;j++) {
temp2=temp1;
temp1=temp1.next;
System.out.println("i="+i);
}
//int id=j+1;
System.out.println("stack"+j+"="+temp2.no);
n++;
}
StackNodes temp1=first.next;
StackNodes temp2=first;
while (temp1.next != null) {
System.out.println("stack=" + temp1.no);
temp2 = temp1;
temp1 = temp1.next;
}
System.out.println("stack=" + temp1.no);
对于show方法的第二次修改:
//二改
//使用链表逆序打印的方法:用一个新链表,把旧链表的最后一个节点每次都加到新链表的头节点之后,然后顺序打印新链表即可
//但是逆序打印会破坏原来链表的结构,所以?????
//StackNodes temp1=first.next;
StackNodes newHead=new StackNodes(0);
//StackNodes temp2=first;
StackNodes temp2=newHead.next;
while(first.next!=null) {//说明有至少1个元素
temp2.next=temp1;
first.next=temp1.next;
temp2=temp2.next;
temp1=first.next;
}
temp2.next=first;
if(newHead.next!=null) {
temp2=newHead.next;
}
while(newHead.next!=null){//新链表有元素
System.out.println(temp2);
temp2=temp2.next;
}
对于show方法的第三次修改:
//三改
//新想法,考虑让first后移,每次把first加到新链表中
StackNodes newHead=new StackNodes(0);
if(newHead.next==null) {
newHead.next=first;
}
StackNodes temp2=newHead.next;
while(first!=null) {
newHead.next=first;
first=first.next;
newHead.next.next=temp2;
temp2=newHead.next;
}
if(newHead.next==null) {
return;
}
StackNodes flag=newHead.next;
while(flag.next!=null){//新链表有元素
System.out.println(flag);
flag=flag.next;
}
整体代码:
//问题:push:只能存入一个数据,pop和show提示空指针
import java.util.Scanner;
//用单链表实现栈:
//需要两个类:用链表模拟栈的类,节点类
public class LinkStack {
public static void main(String[] args) {
// TODO Auto-generated method stub
LinktoStack stack = new LinktoStack(5);
boolean loop = true;
Scanner in = new Scanner(System.in);
String key = null;
while (loop) {
System.out.println("单链表模拟栈:");
System.out.println("输入show,表示显示栈的元素");
System.out.println("输入pop,表示从栈中取出数据");
System.out.println("输入push,表示向栈中添加数据");
System.out.println("输入exit,表示退出程序");
System.out.println("输入指令:");
key = in.next();
switch (key) {
case "show":
stack.show();
break;
case "push":
System.out.println("输入数据:");
int value = in.nextInt();
stack.push(value);
break;
case "pop":// 可能会有运行时异常抛出
try {
int val = stack.pop();
System.out.println("取出的数据:" + val);
}catch(Exception e) {
System.out.println("无法取出数据,栈中数据为:"+e.getMessage());
}
break;
case "exit":
in.close();
loop = false;
break;
default:
break;
}
}
System.out.println("程序退出");
}
}
class LinktoStack {
public int maxSize;
public int top;// 记录栈中元素的数量
public StackNodes head = new StackNodes(0);
public StackNodes first;// 指向第一个元素
public LinktoStack(int maxSize) {
this.maxSize = maxSize;
top = -1;
}
// 判断栈空、栈满,入栈、出栈,显示栈
public boolean isEmpty() {
return top == -1;
}
public boolean isFull() {
return top == maxSize - 1;
}
public void push(int value) {
if (isFull()) {
System.out.println("栈已满");
return;
}
StackNodes node = new StackNodes(value);
top++;
// StackNodes temp = head.next;
if (first == null) {
first = node;
return;
}
// StackNodes temp = head.next;
StackNodes temp = first;
while (true) {
if (temp.next == null) {
break;
}
temp = temp.next;
}
temp.next = node;
}
public int pop() {
if (isEmpty()) {
throw new RuntimeException("栈空");
}
if (first.next == null) {
//StackNodes flag = first;
int value=first.no;
first = null;
top--;
return value;
}
/*
StackNodes temp1 = head.next;// 让temp1指向最后一个元素,temp2为temp1的前一个
StackNodes temp2 = null;
*/
StackNodes temp1=first.next;
StackNodes temp2=first;
while (temp1.next != null) {
temp2 = temp1;
temp1 = temp1.next;
}
int value = temp1.no;
temp2.next = null;
return value;
}
public void show() {
if (first==null) {
System.out.println("栈空");
return;
}
int i=1;
if(first.next==null) {
System.out.println("stack"+i+"="+first.no);
return;
}
i=2;
//遍历链表,获取总元素个数
StackNodes temp1=first.next;
StackNodes temp=first;
while(temp1.next != null) {
temp = temp1;
temp1 = temp1.next;
i++;
}
System.out.println("栈中元素总数:"+i);
//四改,对三改进行修改
//用一个节点只是存储first的数据,每次循环都重新初始化一次
StackNodes newHead=null;
while(temp!=null) {
StackNodes flag=new StackNodes(temp.getNumber());
if(newHead==null) {
newHead=flag;
}else {
flag.next=newHead;
newHead=flag;
}
temp=temp.next;
}
//StackNodes temp2=newHead;
while(newHead!=null) {
System.out.println("stack"+i+"="+newHead.no);
newHead=newHead.next;
i--;
}
}
}
class StackNodes {
public int no;
public StackNodes next;
public StackNodes(int no) {
this.no = no;
}
public int getNumber(StackNodes this) {
return this.no;
}
public String toString() {
return no+"";
}
}