~~~~~~~
栈是一种有序的列表,栈中元素的插入与删除只允许在同一端进行,因此具有先进后出(FILO
)的特点。允许插入和删除的一端,称为栈顶,另一端为固定的一端,称为栈底,可以通过数组或者链表来模拟。本文主要通过Java代码介绍链表模拟栈。
~~~~~~~
本文所使用的链表为自定义双向链表,链表具有一个不存放具体数据的头结点head
,并可使用getHead()
方法获取,同时具有add()
和del()
方法来实现在链表的尾部进行添加、删除结点。每个结点具有一个数据域,两个指针pre
和next
分别指向前一个结点和后一个结点。
~~~~~~~
在栈结构中,通过链表s
来存放数据,入栈和出栈的方法分别为push()
和pop()
,实现思路如下:
push()
方法:传入一个值val
,并通过val
初始化一个结点,然后通过add()
方法加入到链表s
中;pop()
方法:首先通过判断s
中有无数据来得知栈是否为空,如果为空则输出提示信息,如果不为空,首先保存栈顶元素的值,然后通过del()
方法删除尾部结点,即将栈顶元素弹出。
~~~~~~~ 具体实现代码如下:
class LinkedListStack {
private LinkedListForStack s = new LinkedListForStack();
// 栈是否为空
public boolean isEmpty() {
boolean flag = false;
if (s.getHead().next == null)
flag = true;
return flag;
}
// 获取栈顶结点
public NodeForStack getTop() {
NodeForStack temp = s.getHead();
while (temp.next != null) {
temp = temp.next;
}
return temp;
}
// 入栈
public void push(int val) {
NodeForStack node = new NodeForStack(val);
s.add(node);
}
// 出栈
public int pop() {
if (this.isEmpty()) {
throw new RuntimeException("栈为空,没有数据供出栈");
}
int val = this.getTop().val;
s.del();
return val;
}
}
class LinkedListForStack {
// 头节点,不存放数据
private NodeForStack head = new NodeForStack(0);
// 查看头结点
public NodeForStack getHead() {
return head;
}
// 添加一个结点到链表的最后
public void add(NodeForStack node) {
NodeForStack temp = head;
while (temp.next != null) {
temp = temp.next;
}
temp.next = node;
node.pre = temp;
}
// 删除尾部结点
public void del() {
NodeForStack temp = head;
while (temp.next != null) {
temp = temp.next;
}
temp.pre.next = null;
}
}
class NodeForStack {
public int val;
public NodeForStack pre;
public NodeForStack next;
public NodeForStack(int val) {
this.val = val;
}
}