栈
1. 栈的定义
栈是限定仅在表尾进行插入和删除操作的线性表。允许插入、删除的一端称为栈顶(top),另一端称为栈底(bottom),不含任何数据元素的栈称为空栈。
2. 栈的特点
只能在栈顶进行操作,且访问结点时依照后进先出(LIFO)的原则。
3. 栈的基本操作
- 初始化——构造一个空的栈
- 入栈——在栈顶位置插入一个新元素
- 出栈——删除栈顶元素
- 获取——取栈顶元素
- 判空——判断当前栈是否为空
- 求长度——求栈中数据元素的个数
- 正序遍历——依次访问栈中每个元素并输出
- 清空——清空栈
4. 栈的实现
- 顺序栈——顺序存储方式实现
- 链栈——链式存储方式实现
顺序栈代码:
public class SequenceStack<T> {
private final int InitSize = 10; // 初始化长度
private T[] stackArray;
private int top; // top指针,指向栈顶元素的位置
// 默认初始化
public SequenceStack() {
top = -1;
stackArray = (T[]) new Object[InitSize];
}
// 初始化
public SequenceStack(int n) {
if(n < 1) {
System.out.println("初始化长度不合法!");
System.exit(1);
}
top = -1;
stackArray = (T[]) new Object[n];
}
// 栈长度
public int getSize() {
return top + 1;
}
// 判空
public boolean isEmpty() {
return top == -1;
}
// 清空
public void clear() {
top = -1;
stackArray = null;
}
// 遍历
public void nextOrder() {
if(isEmpty()) {
System.out.println("栈为空!");
System.exit(1);
}
for(int i=top; i>=0; i--) {
System.out.print(stackArray[i] + "\t");
}
System.out.println();
}
// 获取栈顶元素
public T getTop() {
if(isEmpty()) {
System.out.println("栈为空!不能进行获取操作!");
return null;
}
return stackArray[top];
}
// 入栈
public void push(T obj) {
if(top + 1 == stackArray.length) {
// 创建一个长度未原来两倍的新数组
T[] temp = (T[]) new Object[top * 2];
// 将旧数组中的值赋值给新数组
for(int i=top; i>=0; i--) {
temp[i] = stackArray[i];
}
// 将stackArray变量指向新数组
stackArray = temp;
}
stackArray[++top] = obj;
}
// 出栈
public T pop() {
if(isEmpty()) {
System.out.println("栈为空!无法进行出栈操作!");
return null;
}
return stackArray[top--];
}
// 测试
public static void main(String[] args) {
int[] arr = {2, 4, 6, 7, 9};
SequenceStack<Integer> stack = new SequenceStack<>();
System.out.println("入栈:");
for (int i = 0; i < arr.length; i++) {
stack.push(arr[i]);
}
stack.nextOrder();
System.out.println("获取栈顶元素:");
System.out.println(stack.getTop());
System.out.println("获取栈长度:");
System.out.println(stack.getSize());
System.out.println("出栈:");
stack.pop();
stack.nextOrder();
System.out.println("9,111入栈:");
stack.push(99);
stack.push(111);
stack.nextOrder();
System.out.println("清空栈:");
stack.clear();
stack.nextOrder();
}
}
测试结果:
链栈代码:
class Node<T> {
T data;
Node<T> next;
public Node(Node<T> next) {
this.next = next;
}
public Node(T data, Node<T> next) {
this.data = data;
this.next = next;
}
}
public class LinkStack<T> {
private int length; // 栈的长度
private Node<T> top; // top指针,指向栈顶元素的位置
// 初始化
public LinkStack() {
top = null;
length = 0;
}
// 栈长度
public int getSize() {
return length;
}
// 判空
public boolean isEmpty() {
return top == null;
}
// 清空
public void clear() {
top = null;
length = 0;
}
// 遍历输出
public void nextOrder() {
if(isEmpty()) {
System.out.println("栈为空!");
}
Node<T> p = top;
while(p != null) {
System.out.print(p.data + "\t");
p = p.next;
}
System.out.println();
}
// 入栈
public void push(T obj) {
top = new Node<>(obj, top);
length++;
}
// 获取栈顶元素
public T getTop() {
if (isEmpty()) {
System.out.println("栈为空!");
return null;
}
return top.data;
}
// 出栈
public T pop() {
if(isEmpty()) {
System.out.println("栈为空!不能进行出栈操作!");
return null;
}
T temp = top.data;
top = top.next;
length--;
return temp;
}
// 测试
public static void main(String[] args) {
LinkStack<Integer> ls = new LinkStack<>();
int[] arr = {12, 14, 16, 18};
// 入栈
for (int i = 0; i < arr.length; i++) {
ls.push(arr[i]);
}
ls.nextOrder(); // 遍历
System.out.println("出栈后:");
ls.pop(); // 出栈
ls.nextOrder(); // 遍历
System.out.println("栈长度:" + ls.getSize()); // 栈长度
System.out.println("栈顶元素:" + ls.getTop());
}
}
测试结果: