(带头)链栈与顺序栈区别
链栈和顺序栈的区别在于,链栈不受空间限制,根据链表生成,如图,首先观察它的特点:
灰色表示真实数据,而top指向的结点,称之为头结点,它的数据项没存入数据,仅仅是做为一个头结点存在。在链栈的初始化中,首先创建了一个头结点,但是里面没有存放数据,如果可能,存放链栈的长度也是可以的。
像顺序栈一样,我们先创建Node结点类,还有创建要用到的接口类
接口类
public interface IStack {
public void clear();
public boolean isEmpty();
public int length();
public Object peek() ;
public void push(Object x)throws Exception;
public Object pop();
public void display();
}
Node结点类
public class Node {
public Object data; //存结点值
public Node next; //后继结点的引用
//无参时的构造函数
public Node() {
this(null,null);
}
//单参时的构造函数
public Node(Object data) {
this(data,null);
}
//两个参时的构造函数
public Node(Object data, Node next) {
this.data = data;
this.next = next;
}
}
链栈的基本操作实现
判空方法
public boolean isEmpty() {
return top == null;
}
求链栈长度的算法
结合注释理解哦
public int length() {
Node p = top; //初始化,P指向栈顶元素,length记数
int length = 0;
while (p != null) { //从栈顶循环向后查找,直到p指向空
p = p.next; //p指向后继结点p.next
++length; //长度加一
}
return length;
}
代码实现
public void push(Object x) throws Exception {
//压栈
Node p = new Node(x); //构建新节点
p.next = top; //新节点的next指向top
top = p; //新结点p成为顶点
}
链栈元素出栈
@Override
public Object pop() { //出栈
if (isEmpty()) { //栈空
return null;
} else {
Node p = top; //p指向被删除结点
top = top.next; //栈顶元素指向next,原来的p元素被删除
return p.data; //返回顶点的数据域的值
}
}
取栈顶元素
@Override
public Object peek() {
if (!isEmpty()) //栈非空
return top.data; //取栈顶元素top.data并返回其值
else
return null;
}
代码总结
public interface IStack {
public void clear();
public boolean isEmpty();
public int length();
public Object peek() ;
public void push(Object x)throws Exception;
public Object pop();
public void display();
}
Node结点
public class Node {
public Object data; //存结点值
public Node next; //后继结点的引用
//无参时的构造函数
public Node() {
this(null,null);
}
//单参时的构造函数
public Node(Object data) {
this(data,null);
}
//两个参时的构造函数
public Node(Object data, Node next) {
this.data = data;
this.next = next;
}
}
描述类
public class LinkStack implements IStack {
private Object[] stackElem; // 栈存储空间
private Node top;
//栈置空,
@Override
public void clear() {
top = null;
System.out.println("栈已经清空!");
System.out.print("\n");
}
@Override
public boolean isEmpty() {
return top == null;
}
@Override
public int length() {
Node p = top; //初始化,P指向栈顶元素,length记数
int length = 0;
while (p != null) { //从栈顶循环向后查找,直到p指向空
p = p.next; //p指向后继结点p.next
++length; //长度加一
}
return length;
}
@Override
public Object peek() {
if (!isEmpty())//栈非空
return top.data;//取栈顶元素并返回其值
else
return null;
}
@Override
public void push(Object x) throws Exception {
//压栈
Node p = new Node(x);//构建新节点
p.next = top;//新节点的next指向top
top = p;//新结点p成为顶点
}
@Override
public Object pop() {//出栈
if (isEmpty()) {//栈空
return null;
} else {
Node p = top;//p指向被删除结点
top = top.next;//栈顶元素指向next,原来的p元素被删除
return p.data;//返回顶点的数据域的值
}
}
@Override
public void display() {
System.out.println("栈的所有元素如下:");
Node p = top;// 取出带头结点的链栈表中的首结点元素
while (p != null) {
System.out.print(p.data.toString() + " ");// 输出数据元素的值
p = p.next;// 取下一个结点
}
System.out.println();
}
}
测试类
public static void main(String[] args) throws Exception {
LinkStack L=new LinkStack();
boolean loop=true;
Scanner sc=new Scanner(System.in);
while(loop){
System.out.println("请选择下列数字进行相应的操作:");
System.out.println("1、求栈的长度");
System.out.println("2、判断栈是否为空");
System.out.println("3、清空栈");
System.out.println("4、取栈顶元素");
System.out.println("5、入栈的操作");
System.out.println("6、出栈操作");
System.out.println("7、显示所有元素");
System.out.println("8、退出");
System.out.println("--------------------------------------------");
System.out.println("\t\t\t\t\t\t\t20软工12班 ");
int n=sc.nextInt();
switch(n){
case 1:{
System.out.println("栈的长度为:"+L.length());
break;
}
case 2:{
L.isEmpty();
break;
}
case 3:{
L.clear();
break;
}
case 4:{
L.peek();
break;
}
case 5:{
System.out.println("请输入入栈元素:");
int s=sc.nextInt();
L.push(s);
break;
}
case 6:{
L.pop();
break;
}
case 7:{
L.display();
break;
}
case 8:{
System.exit(0);
break;
}
default:
}
}
}
}
测试结果
感谢各位大哥观看!