栈(stack)是一种线性数据结构,它就像一个放入乒乓球的圆筒容器,栈中的元素只能先入后出(First In Last Out,简称FILO)。最早进入的元素存放的位置叫作栈底(bottom),最后进入的元素存放的位置叫作栈顶(top)。
栈的特点
线性结构
线性表就是数据排成像一条线一样的结构。每个线性表上的数据最多只有前和后两个方向。其实除了栈,链表、队列、数组等也是线性表结构。
后进先出
关于“栈”,有一个非常贴切的例子,就是一摞叠在一起的盘子。我们平时放盘子的时候,都是从下往上一个一个放;取的时候,我们也是从上往下一个一个地依次取,不能从中间任意抽出。后进者先出,先进者后出,这就是典型的“栈”结构。
栈的实现方式
顺序栈
栈的数组实现如下:
链栈
栈的链表实现如下:
栈的基本操作
进栈
入栈操作(push)就是把新元素放入栈中,只允许从栈顶一侧放入元素,新元素的位置将会成为新的栈顶。这里我们以数组实现为例。
出栈
出栈操作(pop)就是把元素从栈中弹出,只允许从栈顶一侧弹出元素,栈顶的前一个位置的元素将会成为新的栈顶。这里我们以数组实现为例。
栈的具体实现
栈的数组实现
package 栈;
/**
* 栈的数组实现
* @author 15447
*
*/
public class ArrayStack {
private String[] items;
// 栈中元素个数
private int count;
// 栈容量
private int n;
// 通过有参构造初始化栈
public ArrayStack(int n) {
this.items = new String[n];
this.n = n;
this.count = 0;
}
/**
* 入栈操作
* @param item 入栈元素
*/
public void push(String item) throws Exception {
if (count>=n) {
throw new IndexOutOfBoundsException("超出栈容量");
}
items[count] = item;
++count;
}
/**
* 出栈操作
*/
public void pop() throws Exception {
if (count==0) {
throw new IndexOutOfBoundsException("栈中无元素");
}
--count;
}
/**
* 输出栈
*/
private void output() {
for(int i=0; i<count; i++) {
System.out.println(items[i]);
}
}
public static void main(String[] args) throws Exception {
ArrayStack arrayStack = new ArrayStack(5);
arrayStack.push("Lw中");
arrayStack.pop();
arrayStack.output();
}
}
栈的链表实现
package 栈;
/**
* 栈的链表实现
* @author 15447
*
*/
public class LinkedStack {
private Node head;
private Node last;
private int size;
/**
* 入栈
* @param data
*/
public void push(String data) {
Node pushNode = new Node(data);
// 当栈中的节点为空时
if (size==0) {
head = pushNode;
last = pushNode;
} else {
head.next = pushNode;
last = pushNode;
}
size++;
}
/**
* 出栈
*/
public void pop() throws Exception {
if (size==0) {
throw new IndexOutOfBoundsException("栈为空");
} else if(size==1) {
head = null;
last = null;
}
else {
Node preNode = get(size);
preNode.next = null;
last = preNode;
}
size--;
}
/**
* 查找尾节点的前一个结点
* @param size
*/
public Node get(int number) {
Node curNode = head;
for(int i=0; i<number-2; i++) {
curNode = head.next;
}
return curNode;
}
/**
* 输出链表
*/
public void output() {
Node temp = head;
while(temp != null) {
System.out.println(temp.data);
temp = temp.next;
}
}
// 节点类,包括数据域,指针域
private static class Node {
String data;
Node next;
public Node(String data) {
this.data = data;
}
}
public static void main(String[] args) throws Exception {
LinkedStack linkedStack = new LinkedStack();
linkedStack.push("Lw中");
linkedStack.push("Lw中1");
linkedStack.push("Lw中2");
linkedStack.pop();
linkedStack.pop();
linkedStack.pop();
linkedStack.output();
}
}
栈的应用
1:面包屑导航,使用户在浏览页面时可以轻松地回溯到上一级或更上一级页面。
2:借助栈来检查表达式中的括号是否匹配。
3:借助栈来实现表达式求值。