在写算法中用于java的util中已经为我们提供好了Stack类,虽然方便了我们代码书写,但是要想搞懂栈真正的工作流程,我还是建议大家尝试一下自己用数组或者链表的方法手写一个栈试试。
基于数组实现栈
在实现之前我们先补充一点,关于top(栈顶)的位置,有的是指在栈顶元素,有的是指在栈顶元素上一个空元素的位置,这里都可以,指向哪里都行,也可以根据具体的要求选择更合适的方案。(这里我采用第二种)
先想想我们要实现那些功能:
- 初始化
- 入栈push
- 出栈pop
- 显示置顶元素peek
- 判空isEmpty
- 扩容expandCapacity
这里处理好入栈出栈就可以啦,下面是我的实现方法:
import java.util.Arrays;
class Mystack<T>{
//实现栈的数组
private object[]stack;
//栈顶元素
private int top;
//初始化
Mystack(){
//初始容量为10
stack = new object[10];
}
//判断是否为空
public boolean isEmpty(){
return top =0;
}
//返回栈顶元素
public T peek(){
T t = null;
if (top > 0){
t = (T)stack[top -1];
}
return t;
}
//入栈
public void push(T t){
expandCapacity(top + 1);
stack[top]=t;
top++;
}
//出栈
public T pop(){
T t = peek();
if (top > 0){
stack[top -1] = null;
top--;
}
return t;
}
//扩大容量
public void expandCapacity(int size){
int len = stack.length;
if (size > len){
size=size*3/2+1;//每次扩大50%
stack Arrays.copyof(stack,size);
}
}
}
基于链表实现栈
这里使用的是直接插入法,就是没有虚拟结点时对链表头元素进行插入和删除的操作方法,而与这里基于链表实现栈是完全一致的。
代码实现也不复杂,完整实现如下:
class Liststack<T>{
//定义链表
class Node<T>{
public T t;
public Node next;
}
public Node<T> head;
//构造函数初始化头指针
Liststack(){
head null;
}
//入栈
public void push(T t){
if (t =null){
throw new NullPointerException("参数不能为空");
}
if (head =null){
head = new Node<T>();
head.t = t;
head.next = null;
}else{
Node<T>temp =h ead;
head = new Node<>();
head.t = t;
head.next = temp;
}
}
//出栈
public T pop(){
if (head =null){
return null;
}
T t = head.t;
head = head.next;
return t;
}
/取栈顶元素
public T peek(){
if (head =null){
return null;
}
T t = head.t;
return t;
}
/栈空
public boolean isEmpty(){
if (head =null)
return true;
else
return false;
}
}