数据结构-栈
栈与队列
栈
概念
栈:是限定仅在表尾进行插入和删除操作的线性表
。
栈顶(top):允许插入和删除的一端,即表尾称为栈顶
栈底(bottom):表头称为栈底
栈是LIFO结构,后进先出。
与线性表相比,特殊之处在于
限制了线性表的插入和删除位置,始终在栈顶进行。
所以栈底是固定的,最先进栈的只能在栈底
相关操作
栈的插入操作 —> 进栈(圧栈、入栈)
栈的删除操作 —> 出栈(弹栈)
假设入栈元素从小到大,出栈的每个元素后面比该元素小的元素,应该按从大到小的相对顺序排列
比如数字元素1、2、3依次进栈,
出栈顺序可能是 1、2、3
/ 1、3、2
/ 2、1、3
/ 2、3、1
/ 3、2、1
不可能是 3、1、2
的出栈顺序。
抽象数据类型
栈的顺序存储结构
用数组实现
ArrayStack.java
package com.stack; /** * 用数组实现的顺序表 * 限制操作端,使其成为栈 */ public class ArrayStack { private int maxSize; private int[] stack; private int top = -1; public ArrayStackDemo(int maxSize) { this.maxSize = maxSize; stack = new int[maxSize]; } public boolean isFull() { return top == maxSize - 1; } public boolean isEmpty() { return top == -1; } public void push(int value) { // 入栈 if (isFull()) { System.out.println("栈满了"); return; } stack[++top] = value; } public int pop() { // 出栈 if (isEmpty()) { throw new RuntimeException("栈空"); } return stack[top--]; } public void list() { if (isEmpty()) { System.out.println("没有数据"); return; } for (int i = top; i >= 0; i--) { System.out.printf("stack[%d]=%d\n",i,stack[i]); } } }
栈的链式存储结构
简称链栈
LinkStack.java
package com.stack; /** * 因为头结点是必须的,栈顶指针也是必须的。 * 所以合二为一!即初始化的时候不需要头结点 */ public class LinkStack { private Node top; public boolean isFull() { return false; } public boolean isEmpty() { return top == null; } public void push(int num) { // 很少满栈,直接创建结点头插 Node node = new Node(num); node.next = top; top = node; } public int pop() { // 出栈 if (isEmpty()) { throw new RuntimeException("栈空"); } int value = top.data; top = top.next; return value; } public void list() { if (isEmpty()) { System.out.println("没有数据"); return; } Node temp = top; while (temp != null) { System.out.print(temp.data+"\t"); temp = temp.next; } } } class Node{ public int data; public Node next; public Node() { } Node(int data) { this.data = data; } }
Java中自带封装好的Stack类,可以直接使用。
底层继承关系 class Stack<E> extends Vector<E>
用数组存储,如果栈满会自动扩容。
对比
顺序栈与链栈,它们在时间复杂度上是一样的,均为0(1)。
对于空间性能,顺序栈需要事先确定一个固定的长度,可能会存在内存空间浪费的问题,
但它的优势是存取时定位很方便,
而链栈则要求每个元素都有指针域,这同时也增加了一些内存开销,但对于栈的长度无限制。
所以它们的区别和线性表中讨论的一样,如果栈的使用过程中元素变化不可预料,有时很小,
有时非常大,那么最好是用链栈,反之,如果它的变化在可控范围内,建议使用顺序栈会更好一些。
栈的作用
- 递归
- 逆波兰式
- 中缀转后缀
相关推荐
koushr 2020-11-12
zhangxiafll 2020-11-13
kikaylee 2020-10-31
范范 2020-10-28
MILemon 2020-10-22
hugebawu 2020-10-12
LauraRan 2020-09-28
shenwenjie 2020-09-24
omyrobin 2020-09-23
guangcheng 2020-09-22
qiangde 2020-09-13
hanyujianke 2020-08-18
晨曦之星 2020-08-14
xiesheng 2020-08-06
KAIrving 2020-08-02
xiesheng 2020-08-02
范范 2020-07-30
chenfei0 2020-07-30