基础知识:
1.栈是一种特殊的线性表,其插入和删除操作只允许在线性表的一端操作。
2.允许操作的一端叫:栈顶(top),不允许操作的一端叫:栈底(pop)。
3.栈的最大特点:遵循先进先出原则
4.栈一般分为两种:顺序栈 和 链式栈
根据其特点,栈的结构图一般为:
顺序栈: 采用顺序存储结构的栈称为顺序栈。
下面是顺序栈的构建代码:
package practice;
import java.util.*;
//顺序栈
class SeqStack<T> {
private Object element[]; //存储栈数据元素的数组
private int top; //栈顶元素的下标
//构造容量为size的空栈
public SeqStack(int size) {
this.element = new Object[size];
this.top = -1;
}
//构造默认容量的空栈
public SeqStack() {
this(10);
}
//判断栈是否为空,若空返回true
public boolean isEmpty() {
return this.top == -1;
}
//元素x入栈,空对象不能入栈
public void push(T x) {
if(x == null) return;
if(this.top == element.length - 1) {
Object[] temp = this.element;
this.element = new Object[temp.length * 2]; //重新申请一个更大的数组
for(int i = 0; i < temp.length; i++) { //复制数组
this.element[i] = temp[i];
}
}
this.top++;
this.element[this.top] = x;
}
//出栈,返回栈顶元素,若栈空返回null
public T pop() {
return this.top == -1 ? null : (T)this.element[this.top--];
}
//取栈顶元素,未出栈,若栈空返回null
public T get() {
return this.top == -1 ? null : (T)this.element[this.top];
}
}
public class Stack {
public static void main(String[] args) {
//测试
SeqStack<Integer> s = new SeqStack<Integer>();
for(int i = 0; i < 10; i++) {
s.push(i);
}
System.out.println();
for(int i = 0; i < 10; i++) {
System.out.print(s.pop()+"\t");
}
System.out.println();
System.out.print(s.isEmpty());
}
}
下面是测试数据结果:
由于栈只能在栈顶位置进行插入、删除操作,所以push(),pop()和get()方法的时间复杂度为O(1);当需要扩充栈容量,push()方法的时间复杂度为O(n)。
链式栈: 采用链式存储结构的栈称为链式栈。
它的构建结构图为:
下面是链式栈的构造代码:
package practice;
import java.util.*;
//单链表结点类
class Node<T>{
public T data;
public Node<T> next;
public Node(T data, Node<T> next) { //next指向后继结点
this.data = data;
this.next = next;
}
public Node() {
this(null,null);
}
}
//
class LinkedStack<T>{
private Node<T> top; //栈顶结点
//构造空栈
public LinkedStack() {
this.top = null;
}
//判断是否为空
public boolean isEmpty() {
return this.top == null;
}
//元素x入栈
public void push(T x) {
if(x != null) {
this.top = new Node(x,this.top); //采用头插入法
}
}
//出栈
public T pop() {
if(this.top == null) return null;
T temp = this.top.data;
this.top = this.top.next;
return temp;
}
//取栈顶元素
public T get() {
return this.top == null ? null : this.top.data;
}
}
public class Stack {
public static void main(String[] args) {
//测试
LinkedStack<Integer> s = new LinkedStack<Integer>();
for(int i = 0; i < 10; i++) {
s.push(i);
}
System.out.println();
for(int i = 0; i < 10; i++) {
System.out.print(s.pop()+"\t");
}
System.out.println();
System.out.print(s.isEmpty());
}
}
下面是结果数据:
由于链表的一大特点便是它的长度可以不断延长,而且在这里不需要遍历单链表因而push(),pop(),get()方法的时间复杂度都为O(1)。
栈的一些小应用:
1.栈是嵌套调用机制的实现基础
2.使用栈可以以非递归方式实现递归算法
3.符合很多实际应用的情况,易于解决实际问题
END
给自己收藏一个表情包(超级喜欢哈哈哈哈哈)