2019-数据结构-数据结构3.1-stack and queue
Stack and Queue
- 栈和队列是逻辑上的结构,在物理上可以用数组和链表来实现。
1. 栈
- A stack is a list in which insertions and deletions take place at the same end. This end is called the top. The other end of the list is called the bottom. It is also called a LIFO(last-in-first-out) list. 栈是一个插入和删除都发生在最后面的链表,这个最后面被我们称作top,而链表的另一边被我们称作bottom.这个链表被我们成为LIFO(后进先出)列表
- 理论上有方法:push,pop
1.1. 栈的模型
1 |
|
1.2. 栈的实现
1.2.1. 单链表实现
- 最后面是栈底,而表头是栈顶。
1
2
3
4
5
6
7
8
9
10
11
public class StackLi {
public StackLi(){ topOfStack = null; }
public boolean isFull(){ return false; }
public boolean isEmpty(){ return topOfStack = = null; }
public void makeEmpty(){ topOfStack = null; }
public void push(object x)
public object top()
public void pop() throws Underflow;
public object topAndPop()
private ListNode topOfStack;
}
单链表栈的方法实现
1 |
|
1 |
|
1.2.2. 数组实现栈
- 数组靠后的部分(如上图)是栈顶。
栈的数组实现
1
2
3
4
5
6
7
8
9
10
11
12
public class stackAr {
public StackAr()
public StackAr(int capacity)
public boolean isEmpty(){ return topOfStack = = -1; }
public boolean isFull(){ return topOfStack = = theArray.length – 1; }
public void makeEmpty(){ topOfStack = -1; }
public void push(object x) throws overflow public object top()
public void pop() throws Underflow public object topAndPop()
private object [] theArray;
private int topOfStack;
static final int DEFAULT_CAPACITY = 10;
}
数组实现的栈的方法实现
1 |
|
1 |
|
1.3. 栈的特点
- 无论是什么方法,时间复杂度都是O(1)
1.4. 创新的栈的实现
- 从两头向中间存储栈
1.5. 栈的使用
1.5.1. Balancing Symbols(Parenthesis Matching) 括号匹配
1 |
|
1.5.2. 例二:Expression Evaluation
- 中缀表达式变成后缀表达式
- 根据操作的元数来决定弹出几个来进行计算
- 分量是指除了运算符以外的值
1 |
|
中缀表达式转换后缀表达式
- 基本想法:
- 遇到操作数(运算分量)直接输出。
- 遇到操作符:当前的操作符一定是不输出的,如果当前运算符低于栈顶预算符优先级低,则输出,一直到当前运算符高于栈顶运算符优先级
- 括号比较麻烦:需要单独处理
- 左半括号需要压栈,也就是只要保证任何一个优先级低就行,也就是我们希望左半括号永远不要输出出来,在遇到右半括号的时候出去左半括号。
- 每一个符号都有两个优先级,加减乘除的两个优先级都是一样的,而括号的优先级不是。
- 经过计算和推断,我们可以得知一个优先级体系是不能满足
1 |
|
2. 队列
- 两头开,从一边进入,从一边出。
- A queue is a linear list in which additions and deletions take place at different ends. It is also called a first-in-first-out list. The end at which new elements are added is called the rear. The end from which old elements are deleted is called the front. 一个队列是一个添加和删除在不同端发生的线性链表,这个队列
2.1. Queue Model
1 |
|
2.2. 队列的数组实现
- 我们可以用移动队列前后指针来减少方式数据中元素的移动。
- 将数据看成一个圈,当队列队尾指针到数组尾部时,调整到数组头部。
- back = (back + 1) % theArray.length
- rear = (rear + 1) % theArray.length
2.3. 队列的单链表实现
1 |
|
- NULL是定义在0中
2.3.1. 一些方法的实现
2.4. 应用
2.4.1. 杨辉三角
- 一行打印,另一行进队完成
1 |
|
- 队列数组的java实现
1 |
|
2.4.2. 寻找路径 Wire Routing
- 步骤:
- 搜索过程
- 先从位置a(3,2)开始, 把a可到达的相邻方格都表为1( 表示与a相距为1). 注意: 具体实现时, 将a位置置为2, 其它相邻方格为a位置的值+1
- 然后把标记为1的方格可到达的相邻方格都标记为2( 表示与a相距为2).
- 标记过程继续进行下去, 直至到达b或找不到可到达的相邻方格为止. 本例中, 当到达b时, b上的表记为9(实现时为9+2=11)
- 构造a—>b的路径. 从b回溯到a
- 从b出发, 并将b的位置保存在path中. 首先移动到比b的编号小1的相邻 位置上(5,6)
- 接着再从当前位置继续移动到比当前标号小1的相邻位置上.
- 重复这一过程, 直至到达a.
- 搜索过程
- 代码实现
1 |
|
- 代码复杂度
- 网格编号过程:O(m*m)
- 重构过程O(Pathlen)
3. 2009年全国考研统考题
- 设将n(n>1)个整数存放到一维数组R中,试设计一个在时间和空间两方面尽可能有效的算法,将R中保有的序列循环左移P(0﹤P﹤n)个位置,即将R中的数据由(X0,X1,…,Xn-1)变换为(Xp,Xp+1,…,Xn-1,X0,X1,…,Xp-1)
- (1)给出算法的基本设计思想。
- (2)根据设计思想,采用C或C++或JAVA语言表述算法,关键之处给出注释。
- (3)说明你所设计算法的时间复杂度和空间复杂度
- 方法一:先存p个数据,然后移动后面的数据,再次拷贝
- 方法二:存下X0,移动Xp,然后放置xp中应该放的东西,然后调整即可。
2019-数据结构-数据结构3.1-stack and queue
https://spricoder.github.io/2020/01/17/2019-Data-Structure/2019-Data-Structure-%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%843.1-stack%20and%20queue/