目录
- 栈的特性
- 使用场景
- 数组模拟栈
- 链表模拟栈
栈的特性
栈的数据结构:先进后出
、只能在栈顶进行添加(入栈)或删除(出栈)
栈的使用场景
- Android的Activity栈
- 链表节点的反向打印,可以结合栈打印出来
链表遍历时,把节点数据压入栈,把栈打印出来就是对应链表的反向打印
数组模拟栈
思路:
- 定义一个int类型的指针表示栈顶: top
- 每次添加(入栈)数据,top++
- 每次删除(出栈)数据,top–
代码实现
/**
* Created by joker on 2020-06-08
* Describe: 数组模拟Stack
* 思路:数组模拟
* 1. 定义一个int类型的指针表示栈顶: top
* 2. 每次添加(入栈)数据,top++
* 3. 每次删除(出栈)数据,top--
*/
public class ArrayStack {
public static void main(String[] args) throws InterruptedException {
ArrayStack arrayStack = new ArrayStack(7);
arrayStack.push(3);
arrayStack.push(2);
arrayStack.push(4);
arrayStack.push(1);
arrayStack.push(6);
arrayStack.push(5);
arrayStack.push(8);
arrayStack.push(20);
arrayStack.print();
Thread.sleep(500);
log("栈取数据 --------------pop");
for (int i = 0; i < 8; i++) {
int pop = arrayStack.pop();
log("pop取的数据 " + pop);
}
arrayStack.print();
}
/**
* 表示栈顶下表
*/
private int top = -1;
/**
* 栈的最大长度
* 栈满时,栈顶的最大数据的下标 top = stackSzie-1
*/
private int stackSzie;
/**
* 数组存储
*/
private int[] stack;
/**
* 栈满
*/
private boolean isStackFull() {
return (top == stackSzie - 1) ? true : false;
}
/**
* 栈空
*/
private boolean isStackEmpty() {
return (top == -1) ? true : false;
}
public ArrayStack(int stackSzie) {
this.stackSzie = stackSzie;
stack = new int[stackSzie];
}
/**
* 存
*/
public void push(int pushData) {
if (isStackFull())
log("栈满,不能继续存储 " + pushData);
else {
top++;
stack[top] = pushData;
}
}
/**
* 取
*/
public int pop() {
if (isStackEmpty()) {
log("栈的数据已经取完···");
return -1;
} else {
int value = stack[top];
top--;
return value;
}
}
public void print() {
if (stack == null) return;
for (int x = top; x > -1; x--) {
log("top = " + top + " " + stack[x]);
// 这里不做真实的移除数据了
}
}
public static void log(Object obj) {
System.out.println("stack : " + obj);
}
}
链表模拟栈
思路
- 入栈时利用链表的头插法
- 出栈时,取出链表头节点后的第一个节点,让头节点的next直接指向,当前要出栈的节点数据next指向的数据
解释
:
例如:head.next -> A.next ->B.next
删除A节点后 :head.next -> B.next
代码实现:
/**
* Created by joker on 2020-06-08
* Describe: 链表模拟Stack
* 思路:
* 1. 入栈时利用链表的头插法
* 2. 出栈时,取出链表头节点后的第一个节点,让头节点的next直接指向,当前要出栈的节点数据next指向的数据
* 解释:-> 例如:head.next -> A.next ->B.next
* 删除A节点后 : head.next -> B.next
*/
public class LinkListStack {
public static void main(String[] args) {
LinkListStack linkListStack = new LinkListStack();
linkListStack.pushNode(new StackNode(1));
linkListStack.pushNode(new StackNode(4));
linkListStack.pushNode(new StackNode(3));
linkListStack.pushNode(new StackNode(2));
linkListStack.pushNode(new StackNode(5));
linkListStack.print();
log("pop-----------");
log("pop = " + linkListStack.popNode().num);
log("pop = " + linkListStack.popNode().num);
log("pop = " + linkListStack.popNode().num);
linkListStack.print();
}
private StackNode firstNode = new StackNode(-1);
/**
* 链表模拟栈
* 保持一个原则:头插法
* 每次push数据,都插在链表head节点后的第一个节点
*/
public void pushNode(StackNode addNode) {
StackNode temp = firstNode;
if (temp.next == null) {
temp.next = addNode;
} else {
addNode.next = temp.next;
temp.next = addNode;
}
}
public StackNode popNode() {
StackNode temp = firstNode;
StackNode returnNode = null;
if (temp.next == null) {
log("链表空。。。。");
} else {
returnNode = temp.next;
temp.next = temp.next.next;
}
return returnNode;
}
private void print() {
StackNode temp = firstNode.next;
while (temp != null) {
log(temp.num);
temp = temp.next;
}
}
static class StackNode {
private int num;
private StackNode next;
public StackNode(int num) {
this.num = num;
}
@Override
public String toString() {
return "StackNode{" +
"num=" + num +
", next=" + next +
'}';
}
}
public static void log(Object obj) {
System.out.println("stack : " + obj);
}
}