一、概述
栈是一种受限的线性数据结构,它对元素的操作遵循的是先进后出
二、链栈
2.1 API设计
类名 | Stack |
---|---|
构造方法 | Stack():创建Stack对象 |
成员方法 | 1.public boolean isEmpty():判断栈是否为空,是返回true,否返回false 2.public int size():获取栈中元素的个数 3.public T pop():弹出栈顶元素 4.public void push(T t):向栈中压入元素t |
成员变量 | 1.private Node head:记录首结点 2.private int N:当前栈的元素个数 |
2.2 实现
2.2.1 节点类
private class Node{
public T item;
public Node next;
public Node(T item, Node next){
this.item = item;
this.next = next;
}
}
2.2.2 链栈
public class Stack<T> implements Iterable<T> {
// 记录首节点
private Node head;
// 栈中元素的个数
private int N;
public Stack(){
head = new Node(null,null);
N=0;
}
private class Node{
public T item;
public Node next;
public Node(T item, Node next){
this.item = item;
this.next = next;
}
}
// 判断当前栈中元素的个数是否为0
public boolean isEmpty(){
return N == 0;
}
// 把t元素压入栈
public void push(T t){
Node oldHead = head.next; // 首个存储数据的节点
Node newNode = new Node(t, oldHead);
head.next = newNode;
N++;
}
// 弹出栈顶元素
public T pop(){
// 暂存首个存储元素的节点
Node oldNext = head.next;
if (oldNext==null){
// 避免之后拿元素时报空指针异常
return null;
}
// 删除首个元素
head.next = head.next.next;
// 个数-1
N--;
return oldNext.item;
}
// 获取栈中元素个数
public int size(){
return N;
}
@Override
public Iterator<T> iterator() {
return new SIterator();
}
private class SIterator implements Iterator<T>{
private Node n = head; // 遍历的元素
@Override
public boolean hasNext() {
return n.next!=null;
}
@Override
public T next() {
n = n.next;
return n.item;
}
}
}
2.3 测试
public class StackTest {
public static void main(String[] args) {
Stack<String> stack = new Stack<>();
stack.push("a");
stack.push("b");
stack.push("c");
stack.push("d");
for (String str : stack) {
System.out.print(str + " ");
}
System.out.println("-----------------------------");
String result = stack.pop();
System.out.println("弹出了元素:" + result);
System.out.println(stack.size());
}
}
三、顺序栈
3.1 API设计
类名 | ArrayStack |
---|---|
构造方法 | ArrayStack():创建ArrayStack对象 |
成员方法 | 1.public boolean isEmpty():判断栈是否为空,是返回true,否返回false 2.public int size():获取栈中元素的个数 3.public T pop():弹出栈顶元素 4.public void push(T t):向栈中压入元素t |
成员变量 | 1.private T[] stack:存储元素的数组 2.private int N:当前栈的元素个数 |
3.2 实现
/**
* 顺序栈
*
* @date 2021/6/17 10:40
* todo:数组自动扩容
*/
public class ArrayStack<T> implements Iterable<T> {
// 存储元素的数组
private T[] stack;
// 栈中元素的个数
private int N;
// 构造器
public ArrayStack(int capacity) {
this.stack = (T[]) new Object[capacity];
this.N = 0;
}
// 判断栈是否为空
public boolean isEmpty() {
return N == 0;
}
// 获取栈中元素的个数
public int size() {
return N;
}
// 弹出栈顶元素,假设数组最后一个元素为栈顶
public T pop() {
if (isEmpty()) {
return null;
}
T t = stack[N - 1];
N--;
return t;
}
// 向栈中压入元素t
public void push(T t) {
if (N == stack.length) {
throw new RuntimeException("栈已经存满了!");
}
stack[N++] = t;
}
@Override
public Iterator<T> iterator() {
return new SIterator();
}
private class SIterator implements Iterator<T> {
private int index;
public SIterator() {
this.index = 0;
}
@Override
public boolean hasNext() {
return index < N;
}
@Override
public T next() {
return stack[index++];
}
}
}
3.3 测试
public class ArrayStackTest {
public static void main(String[] args) {
ArrayStack<String> stack = new ArrayStack<>(15);
stack.push("a");
stack.push("b");
stack.push("c");
stack.push("d");
for (String str : stack) {
System.out.print(str + " ");
}
System.out.println("-----------------------------");
String result = stack.pop();
System.out.println("弹出了元素:" + result);
System.out.println(stack.size());
}
}