1.基于数组实现栈
首先要明确,栈的常用方法有哪些?
- isEmpty(); 判断栈是否为空
- size(); 栈的大小;
- push(T ele); 元素入栈;
- pop(); 元素出栈;
- peek(); 查看栈顶元素,但栈顶元素不出栈;
代码实现:
/*
* 基于数组手写栈
* */
public class MyStack<T> {
// 数组
private Object[] stack;
// 栈顶位置,也可以理解为栈的大小;
private int top;
private final double threshold = 0.8;
public MyStack() {
stack = new Object[10];
}
// 判断栈中元素是否为空
public boolean isEmpty() {
return top == 0;
}
// 元素入栈
public void push(Object ele) {
if (top < stack.length) {
stack[top++] = ele;
}
// 如果达到扩容阈值,就对数组扩容
if (top >= stack.length * threshold) {
expandCapacity();
}
}
// 查看栈顶元素
public T peek() {
T ele = null;
if (top > 0) {
ele = (T) stack[top - 1];
}
return ele;
}
// 元素出栈
public T pop() {
T ele = peek();
// 如果top > 0 说明栈中还有元素
if (top > 0) {
stack[top - 1] = null;
top--;
}
return ele;
}
// 数组扩容
private void expandCapacity() {
int len = stack.length * 3 / 2;
stack = Arrays.copyOf(stack, len);
}
// 查看当前栈中的元素总个数
public int size() {
return top;
}
// 使用Main方法测试
public static void main(String[] args) {
MyStack<Integer> stack = new MyStack<>();
for (int i = 0; i < 10; i++) {
stack.push(i);
}
stack.push(11);
stack.push(12);
stack.push(13);
stack.push(14);
int size = stack.size();
int res=stack.peek();
int res=stack.pop();
size=stack.size();
}
}
4.基于链表实现栈
先解释一下,这里我为什么要维持一个头节点head ;
首先元素入栈时是这样的:
当待入栈元素是这样的:1,2,3,4,5;
此时形成的链表结构为:
此是我们插入元素时,只要进行尾插法即可;但是删除元素时,需要依靠头节点,遍历到tempNode节点的上一个位置,也就是图中的 4 位置,记作curNode,然后删除tempNode,再将curNode赋值给tempNode即可;
还有一种可以形成的链表结构:
每次插入时将新的节点插入到链表的头部,这样元素在出栈时就不用在做过多的处理,直接head=head.next;即可
如图:
我是用的第一种实现,仅供参考;
代码如下:
/*
* 基于链表手写栈
* */
public class LinkedStack<T> {
// 定义链表结构
static class LinkedList<T> {
T val;
LinkedList<T> next;
public LinkedList(T val) {
this.val = val;
}
}
// 定义头节点
private LinkedList<T> head;
// 栈顶元素
private LinkedList<T> tempNode;
// 栈的大小
private int size;
// 初始化链表结构
public LinkedStack() {
head = new LinkedList(-1);
tempNode = head;
}
// 元素入栈
public void push(T ele) {
tempNode.next = new LinkedList<T>(ele);
tempNode = tempNode.next;
size++;
}
// 判断栈为空
public boolean isEmpty() {
return size == 0;
}
// 查看栈顶元素
public T peek() {
T ele = null;
if (head.next != null) {
ele = tempNode.val;
}
return ele;
}
// 元素出栈
public T pop() {
T ele = peek();
if (ele != null) {
LinkedList<T> curNode = head.next;
while (curNode.next.val != ele) {
curNode = curNode.next;
}
LinkedList<T> next = curNode.next;
curNode.next = next.next;
// 因为原来栈顶元素已经出栈,所以需要维持一个新的栈顶元素,也就是curNode;
tempNode = curNode;
size--;
}
return ele;
}
// 栈的大小
public int size() {
return size;
}
// 使用Main方法测试
public static void main(String[] args) {
LinkedStack<String> stack = new LinkedStack();
for (int i = 0; i < 10; i++) {
stack.push(i + "");
}
int size = stack.size();
String val = stack.pop();
size = stack.size();
}
}