2.5 棧
概述
計(jì)算機(jī)科學(xué)中,stack 是一種線性的數(shù)據(jù)結(jié)構(gòu),只能在其一端添加數(shù)據(jù)和移除數(shù)據(jù)。習(xí)慣來說,這一端稱之為棧頂,另一端不能操作數(shù)據(jù)的稱之為棧底,就如同生活中的一摞書
先提供一個(gè)棧接口
public interface Stack<E> {
/**
* 向棧頂壓入元素
* @param value 待壓入值
* @return 壓入成功返回 true, 否則返回 false
*/
boolean push(E value);
/**
* 從棧頂彈出元素
* @return 棧非空返回棧頂元素, 棧為空返回 null
*/
E pop();
/**
* 返回棧頂元素, 不彈出
* @return 棧非空返回棧頂元素, 棧為空返回 null
*/
E peek();
/**
* 判斷棧是否為空
* @return 空返回 true, 否則返回 false
*/
boolean isEmpty();
/**
* 判斷棧是否已滿
* @return 滿返回 true, 否則返回 false
*/
boolean isFull();
}
鏈表實(shí)現(xiàn)
public class LinkedListStack<E> implements Stack<E>, Iterable<E> {
private final int capacity;
private int size;
private final Node<E> head = new Node<>(null, null);
public LinkedListStack(int capacity) {
this.capacity = capacity;
}
@Override
public boolean push(E value) {
if (isFull()) {
return false;
}
head.next = new Node<>(value, head.next);
size++;
return true;
}
@Override
public E pop() {
if (isEmpty()) {
return null;
}
Node<E> first = head.next;
head.next = first.next;
size--;
return first.value;
}
@Override
public E peek() {
if (isEmpty()) {
return null;
}
return head.next.value;
}
@Override
public boolean isEmpty() {
return head.next == null;
}
@Override
public boolean isFull() {
return size == capacity;
}
@Override
public Iterator<E> iterator() {
return new Iterator<E>() {
Node<E> p = head.next;
@Override
public boolean hasNext() {
return p != null;
}
@Override
public E next() {
E value = p.value;
p = p.next;
return value;
}
};
}
static class Node<E> {
E value;
Node<E> next;
public Node(E value, Node<E> next) {
this.value = value;
this.next = next;
}
}
}
數(shù)組實(shí)現(xiàn)
public class ArrayStack<E> implements Stack<E>, Iterable<E>{
private final E[] array;
private int top = 0;
@SuppressWarnings("all")
public ArrayStack(int capacity) {
this.array = (E[]) new Object[capacity];
}
@Override
public boolean push(E value) {
if (isFull()) {
return false;
}
array[top++] = value;
return true;
}
@Override
public E pop() {
if (isEmpty()) {
return null;
}
return array[--top];
}
@Override
public E peek() {
if (isEmpty()) {
return null;
}
return array[top-1];
}
@Override
public boolean isEmpty() {
return top == 0;
}
@Override
public boolean isFull() {
return top == array.length;
}
@Override
public Iterator<E> iterator() {
return new Iterator<E>() {
int p = top;
@Override
public boolean hasNext() {
return p > 0;
}
@Override
public E next() {
return array[--p];
}
};
}
}
應(yīng)用
模擬如下方法調(diào)用
public static void main(String[] args) {
System.out.println("main1");
System.out.println("main2");
method1();
method2();
System.out.println("main3");
}
public static void method1() {
System.out.println("method1");
method3();
}
public static void method2() {
System.out.println("method2");
}
public static void method3() {
System.out.println("method3");
}
模擬代碼
public class CPU {
static class Frame {
int exit;
public Frame(int exit) {
this.exit = exit;
}
}
static int pc = 1; // 模擬程序計(jì)數(shù)器 Program counter
static ArrayStack<Frame> stack = new ArrayStack<>(100); // 模擬方法調(diào)用棧
public static void main(String[] args) {
stack.push(new Frame(-1));
while (!stack.isEmpty()) {
switch (pc) {
case 1 -> {
System.out.println("main1");
pc++;
}
case 2 -> {
System.out.println("main2");
pc++;
}
case 3 -> {
stack.push(new Frame(pc + 1));
pc = 100;
}
case 4 -> {
stack.push(new Frame(pc + 1));
pc = 200;
}
case 5 -> {
System.out.println("main3");
pc = stack.pop().exit;
}
case 100 -> {
System.out.println("method1");
stack.push(new Frame(pc + 1));
pc = 300;
}
case 101 -> {
pc = stack.pop().exit;
}
case 200 -> {
System.out.println("method2");
pc = stack.pop().exit;
}
case 300 -> {
System.out.println("method3");
pc = stack.pop().exit;
}
}
}
}
}