栈
栈的基本概念
定义
栈: 只允许在一端进行插入和删除操作的线性表。
特点
- 栈是一种线性表
- 只允许在一端进行插入删除操作
- 后进先出(LIFO)
栈顶: 进行插入删除的一端
栈底: 固定的,不可以进行插入删除的一端
空栈: 不含任何元素的空表
栈的基本操作
1 2 3 4 5 6
| initStack(&S) stackEmpty(&S) push(&S, x) pop(&S, &x) getTop(S, &x) clearStack(&S)
|
栈的顺序存储结构
实现
1 2 3 4 5
| #define MAX_SIZE 100 typedef struct { ELEM_TYPE data[MAX_SIZE]; int top; } sqStack;
|
链式存储结构
实现
1 2 3 4
| typedef struct linkStack { ELEM_TYPE data; struct linkStack *next; } *linkStack;
|
队列
队列基本概念
队列的定义
也是一种操作受限的线性表,只允许在一端插入,另一端删除。
队列的特点
- 是一种线性表
- 一端插入一端删除,插入称为入队或进队,删除称为离队或出队。
- 先进先出(FIFO)
队头: 允许删除的一端,也称队首
队尾: 允许插入的一端
空队列: 不含任何元素的队列
基本操作
1 2 3 4 5
| initQueue(&Q) queuEmpty(Q) enQueue(&Q, x) deQueue(&Q, &x) getHead(Q, &x)
|
队列的顺序存储结构
1 2 3 4 5
| #define MAX_SIZE 100 typedef struct { ELEM_TYPE data[MAX_SIZE]; int front, rear; } sqQueue;
|
队列的链式存储结构
1 2 3 4 5 6 7 8
| typedef struct linkNode { ELEM_TYPE data; struct linkNode *next; } linkNode;
typedef struct { linkNode *front, *rear; } linkQueue;
|
双端队列
双端队列是指两端都能进行插入删除操作的队列。
其元素的逻辑结构依然是线性的,两端分写称为前端和后端。
输出受限的双端队列
允许在一端进行插入删除,另一端只允许插入的双端队列
输入受限的双端队列
允许在一端进行插入删除,另一端只允许删除的双端队列
队列与栈的运用
典型场景
栈:
- 函数调用,使用栈存储局部变量等
- 表达式计算,使用栈来计算表达式的值或几种表达式的转换
- 迷宫求解
- 进制转换
队列:
中缀表达式转后缀表达式
规则如下
从左向右读一个中缀表达式,维护一个运算符栈
- 如果遇到操作数,将其直接输出
- 如果遇到操作符或”(“,将其入栈
- 如果遇到”)”将栈内的操作符弹出并输出直到”(“为止,括号只弹出不输出
- 如果在栈顶元素不是”(“的情况下遇到其他操作符[“+”, “-“, “*”, “/“]等,从栈中弹出元素直到遇到优先级更低的运算符,或者弹出直到遇到左括号,然后将遇到的操作符入栈。注意:只有遇到右括号”)”时才弹出左括号”(“
- 如果读到了末尾,将栈中所有元素弹出
JS代码实现:
代码的实现只考虑了基本运算符,即加减乘除
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| function infix2suffix(exp) { const o1 = ['+', '-'] const o2 = ['*', '/'] const o3 = ['(', ')'] const operators = [...o1, ...o2, ...o3] const stack = [] const arr = exp.split('').filter(e => e !== ' ') let result = '' arr.forEach(e => { let top = stack[stack.length - 1]; if (!operators.includes(e)) { result += e return } if (!top || e === o3[0]) { stack.push(e) return }
let p1 = getPriority(top) const p2 = getPriority(e)
if (p2 === 3) { for (let o = stack.pop(); o !== o3[0]; o = stack.pop()) { result += o; } return }
while (p2 <= p1 && p1 !== 3) { result += stack.pop() top = stack[stack.length - 1] p1 = getPriority(top) } stack.push(e) return })
while (stack.length > 0) { result += stack.pop() }
return result
function getPriority(o) { if (o1.includes(o)) { return 1 } if (o2.includes(o)) { return 2 } if (o3.includes(o)) { return 3 } } } console.log(infix2suffix('A + B * (C - D) - (E / F)'))
|
EOF