栈是一种先入后出(FILO)的数据结构,其出栈和入栈的时间复杂度均为O(1),实现方式可以是数组或者链表。
栈的应用在于历史的回溯,能够使用递归实现的一般都能使用栈来实现。
数组实现方式
public class MyArrayStack {
private int[] array;
private int size;
public MyArrayStack(int capacity) {
array = new int[capacity];
size = 0;
}
public static void main(String[] args) {
MyArrayStack myArrayStack = new MyArrayStack(4);
myArrayStack.push(1);
myArrayStack.push(2);
myArrayStack.push(3);
myArrayStack.push(4);
myArrayStack.print();
System.out.println(myArrayStack.pop());
System.out.println(myArrayStack.pop());
System.out.println(myArrayStack.pop());
System.out.println(myArrayStack.pop());
}
public int pop() {
if (size <= 0) {
throw new IndexOutOfBoundsException("栈空间已空");
}
int element = array[size - 1];
array[size - 1] = 0;
size--;
return element;
}
public void push(int element) {
if (size >= array.length) {
throw new IndexOutOfBoundsException("栈空间已满");
}
array[size] = element;
size++;
}
public void print() {
for (int i = 0; i < size; i++) {
System.out.print(array[i] + " ");
}
System.out.println();
}
}
数组初始化(入栈):1 2 3 4
出栈:4
出栈:3
出栈:2
出栈:1
链表实现方式
public class MyLinkedListStack {
private Node head;
private Node last;
private int size;
private static class Node {
private int data;
private Node next;
public Node(int data) {
this.data = data;
}
}
public static void main(String[] args) {
MyLinkedListStack stack = new MyLinkedListStack();
stack.push(1);
stack.push(2);
stack.push(3);
stack.push(4);
stack.print();
System.out.println(stack.pop());
System.out.println(stack.pop());
System.out.println(stack.pop());
System.out.println(stack.pop());
}
public void push(int element) {
Node newNode = new Node(element);
if (head == null) {
head = last = newNode;
} else {
last.next = newNode;
last = newNode;
}
size++;
}
public int pop() {
Node removeNode = last;
if (size <= 0) {
throw new IndexOutOfBoundsException("栈空间已空");
}
if (size == 1) {
head = last = null;
} else {
Node preNode = get(size - 2);
preNode.next = null;
last = preNode;
}
size--;
return removeNode.data;
}
public Node get(int index) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException("超出链表实际元素范围");
}
Node node = head;
//这里从0开始遍历,也可以根据索引值决定从头部遍历还是从尾部遍历
for (int i = 0; i < index; i++) {
node = node.next;
}
return node;
}
public void print() {
Node node = head;
while (node != null) {
System.out.print(node.data + " ");
node = node.next;
}
System.out.println();
}
}
链表初始化(入栈):1 2 3 4
出栈:4
出栈:3
出栈:2
出栈:1