1、栈介绍
- 栈的英文为(stack)
- 栈是一个先入后出(FILO-First In Last Out)的有序列表。
- 栈(stack)是限制线性表中元素的插入和删除只能在线性表的同一端进行的一种特殊线性表。允许插入和删除的一端,为变化的一端,称为栈顶(Top),另一端为固定的一端,称为栈底(Bottom)。
- 根据栈的定义可知,最先放入栈中元素在栈底,最后放入的元素在栈顶,而删除元素刚好相反,最后放入的元素最先删除,最先放入的元素最后删除。
- 5)出栈(pop)和入栈(push)如图所示。
2、栈的应用场景
- 子程序的调用:在跳往子程序前,会先将下个指令的地址存到堆栈中,直到子程序执行完后再将地址取出,以回到原来的程序中。
- 处理递归调用:和子程序的调用类似,只是除了储存下一个指令的地址外,也将参数、区域变量等数据存入堆栈中。
- 表达式的转换[中缀表达式转后缀表达式]与求值(实际解决)。
- 二叉树的遍历。 图形的深度优先(depth一first)搜索法。
3、栈的快速入门
(1)栈(Stack)是一个后进先出(Last in first out,LIFO)的线性表,它要求只在表尾进行删除和插入操作。
(2)特点:
- 栈是特殊的线性表(顺序表、链表),它在操作上有一些特殊的要求和限制:栈的元素必须“后进先出”。
- 栈的表尾称为栈的栈顶(top),相应的表头称为栈底(bottom)。
- 栈的操作只能在这个线性表的表尾进行。
(3)栈的接口定义:
public interface IStack<E> {
//1.判断空栈
public boolean isEmpty();
//2.判断栈满
public boolean isMax();
//3.入栈
public boolean push(E e);
//4.出栈
public E pop();
//5.返回栈顶
public E peek();
//6.返回元素在栈中的位置
public int getIndex(E e);
//7.返回栈的实际长度
public int size();
//8.返回栈容量
public int getStackSize();
//9.打印栈
public void display();
}
(4)栈的实现:
public class MyStack<E> implements IStack<E>{
private Object[] data = null; //数据域
private int top = -1; //栈顶指针初始化为-1
private int maxSize = 0; //栈最大容量
//默认设置栈容量为10
MyStack(){
this(10);
}
public MyStack(int initialSize){
if(initialSize >= 0){
this.data = new Object[initialSize]; //初始化数组
this.maxSize = initialSize; //设置栈最大容量
this.top = -1;
}
}
public boolean isEmpty() {
return top == -1 ? true : false; //根据栈顶值判断,如果栈顶指针没有更新,则为空栈
}
public boolean isMax() {
return top >= maxSize-1 ? true : false; //根据栈顶值判断,如果栈顶指针大于最大容量,则为满栈
}
public boolean push(E e) {
if(isMax()){
System.err.println("对不起,栈已满,无法入栈");
return false;
}
top ++; //更新栈顶下标
data[top] = e; //将元素添加到表中
// System.out.println("添加" + e + "成功");
return true;
}
@SuppressWarnings("unchecked")
public E pop() {
if(isEmpty()){
System.err.println("对不起,目前是空栈,没有元素可以出栈");
return null;
}
E e = (E) data[top]; //返回当前的栈顶元素
top--; //更新栈顶
return e;
}
@SuppressWarnings("unchecked")
public E peek() {
if(isEmpty()){
System.err.println("对不起,目前是空栈,无法返回栈顶元素");
return null;
}
return (E) data[top]; //返回栈顶元素
}
public int getIndex(E e) {
//根据栈顶和栈底(-1)遍历栈
while(top != -1){
//peek()返回当前栈顶
if(peek().equals(e)){
return top;
}
top --;
}
return -1;
}
public int size() {
return this.top+1; //栈顶值+1,为栈元素的实际个数
}
public int getStackSize() {
return this.maxSize; //返回栈实际长度
}
public void display() {
//根据栈顶和栈底(-1)遍历
while(top != -1){
System.out.println(top);
top --;
}
}
public static void main(String[] args) {
MyStack<Integer> stack = new MyStack<Integer>();
//入栈
for (int i = 0; i < 10; i++) {
stack.push(i);
}
//出栈
// stack.pop();
//返回栈顶
// System.out.println(stack.peek());
//求长
// System.out.println(stack.size());
}
}
(5)利用栈实现字符串逆序
栈是后进先出,如果将一个字符串分隔为单个的字符,然后将字符一个一个push()进栈,在一个一个pop()出栈就是逆序显示了。如下:将字符串“how are you” 反转!
ps:这里是用上面自定的栈来实现的,可以将ArrayStack替换为JDK自带的栈类Stack试试
//进行字符串反转
@Test
public void testStringReversal(){
ArrayStack stack = new ArrayStack();
String str = "how are you";
char[] cha = str.toCharArray();
for(char c : cha){
stack.push(c);
}
while(!stack.isEmpty()){
System.out.print(stack.pop());
}
}
运行结果:
uoy era woh