前言
栈(Stack):只允许在一端进行插入或删除操作的线性表。
栈顶(Top):线性表允许进行插入删除的那一端。
栈底(Bottom):固定的,不允许操作的另一端。
栈和队列都属于操作受限的线性表,栈的操作特性可以概括为先进后出,它有两种存储结构,分别是顺序存储结构和链式存储结构。顺序存储结构可以采用数组来实现,链式存储结构则采用链表来实现。
栈的实现
1.使用数组来实现
首先定义需要存放的数据的类:
public class T {
private String a;
public T(){
}
public T(String a) {
this.a = a;
}
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
}
新建一个类定义栈。类的属性包括实现栈的数组、数组大小;类的方法包括返回栈顶元素(peek)、入栈(push)、出栈(pop)这三个基本操作,另外可以增加判断栈是否为空isEmpty()。最后进行测试。
class Mystack1 {
//实现栈的数组
private Object[] stack;
//数组大小
private int size;
Mystack1() {
stack = new Object[10];//初始容量为10
}
//判断是否为空
public boolean isEmpty() {
return size == 0;
}
//返回栈顶元素
public T peek() {
T t = null;
if (size > 0)
t = (T) stack[size - 1];
return t;
}
//入栈
public void push(T t) {
expandCapacity(size + 1);
stack[size] = t;
size++;
}
//出栈
public T pop() {
T t = peek();
if (size > 0) {
stack[size - 1] = null;
size--;
}
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);
}
}
}
public class ArrayStack {
public static void main(String[] args) {
Mystack1 stack = new Mystack1();
System.out.println(stack.peek());
System.out.println(stack.isEmpty());
T t1=new T();
t1.setA("java");
T t2=new T();
t2.setA("is");
T t3=new T();
t3.setA("beautiful");
T t4=new T();
t4.setA("language");
stack.push(t1);
stack.push(t2);
stack.push(t3);
stack.push(t4);
System.out.println(stack.pop().getA());
System.out.println(stack.pop().getA());
System.out.println(stack.pop().getA());
System.out.println(stack.pop().getA());
System.out.println(stack.isEmpty());
System.out.println(stack.peek());
}
}
2.使用链表实现
代码如下:
class Mystack2 {
//定义链表
class Node {
private T t;
private Node next;
}
private Node head;
//构造函数初始化头指针
Mystack2() {
head = null;
}
//入栈
public void push(T t) {
if (t == null) {
throw new NullPointerException("参数不能为空");
}
if (head == null) {
head = new Node();
head.t = t;
head.next = null;
} else {
Node temp = head;
head = new Node();
head.t = t;
head.next = temp;
}
}
//出栈
public T pop() {
T t = head.t;
head = head.next;
return t;
}
//栈顶元素
public T peek() {
T t = head.t;
return t;
}
//栈空
public boolean isEmpty() {
if (head == null)
return true;
else
return false;
}
}
public class LinkStack {
public static void main(String[] args) {
Mystack2 stack = new Mystack2();
System.out.println(stack.isEmpty());
T t1=new T();
t1.setA("java");
T t2=new T();
t2.setA("is");
T t3=new T();
t3.setA("beautiful");
T t4=new T();
t4.setA("language");
stack.push(t1);
stack.push(t2);
stack.push(t3);
stack.push(t4);
System.out.println(stack.peek().getA());
System.out.println(stack.peek().getA());
System.out.println(stack.pop().getA());
System.out.println(stack.pop().getA());
System.out.println(stack.isEmpty());
System.out.println(stack.pop().getA());
System.out.println(stack.isEmpty());
}
}
扩展
队列是先进先出的线性表,与栈相似,队列也可以用数组和链表来实现。使用链表实现时,它实际上是一个同时带有头指针和队尾指针的单链表。
备注:本文代码来源于网上公开内容,未找到原作者。