天空之外:点击收听
1 基本知识点
1、栈顶是指允许进行插入和删除操作的一端,另外一端称为栈底
2、进栈是指在栈顶位置插入元素(也叫入栈或者压栈),出栈是指删除栈顶元素(也叫弹栈或者退栈)
3、栈溢出是指:
当栈满的时候,若再进行入栈就会发生上溢
当栈空的时候,若再进行出栈就会发生下溢
4、空栈是指不含有元素的空表
5、栈的实现方法:
顺序栈和链栈
6、顺序栈:使用数组的后端表示栈顶,top常被使用为栈顶指针
栈为空时,栈顶指针:top == -1
进行入栈操作时,需要先去让栈顶指针加一,再去放入元素
进行出栈操作时,需要先去取出栈顶元素,再去让栈顶指针减一
7、链栈:因为栈的基本操作都是在栈顶进行的,所以说使用不带头结点的单链表就可以实现:
需要考虑栈顶元素的插入和删除操作
将单链表的头指针指向栈顶,当栈顶指针top为空的时候表示为空栈
8、入栈操作:
p->data = value;
p->next = top;
top = p;
//p成为新的栈顶元素
9、出栈操作:
p = top;
value = p->data;
top = top->next;
free(p);//删除栈顶元素
return value;//返回栈顶元素的值
10、栈是操作受限的线性表
2 栈的应用
1、中缀表达式求值
假定表达式中只有运算符和操作数两类成分,运算符有(+、-、*、/)和圆括号()
设置两个栈来求解
运算符栈(OperatorStack)SY
操作数栈(OperandStack)SC
算法
首先将SC置为空,将表达式起始符‘=’压入SY中作为栈底元素,然后依次扫描中缀表达式:
1 如果是数字,那么就压入SC中
2 如果是运算符,那么:
2.1若当前的运算符的优先级高于SY的栈顶的运算符,那么就继续入栈
2.2若当前的运算符的优先级低于SY的栈顶的运算符,那么就弹出SY的栈顶的运算符,再从SC中弹出两个操作数,进行相对应运算之后,将结果压入SC栈中
优先级
1、乘除大于加减
2、等号优先级最低
2、将中缀表达式转换为后缀表达式(运算符出现在操作数的后面)
算法
设置一个字符栈和两个字符数组
1 将中缀表达式放在字符数组infix中
2 将后缀表达式放在字符数组postfix中
3 从左到右开始扫描字符数组infix
3.1如果遇到‘(’,那么就压入栈中
3.2如果遇到操作数,那么就直接送入postfix中
3.3如果遇到运算符并且该运算符的级别高于栈顶元素,那么就入栈;否则,栈顶元素就退栈,进入postfix中,infix再去和新的栈顶元素比较,重复3.3
3.4如果遇到‘)’,那么就将栈中的元素依次送入postfix中,直到碰到‘(’,消掉一对括号为止
3.5如果遇到‘=’时候,那么就开始执行退栈操作,然后将退栈的元素依次存入postfix中,直到栈为空
3.6最后在postfix中存入‘\0’作为后缀表达式的结束标志
小技巧
1、添加小括号
2、移动运算符
3、删除小括号
同时这个方法也可以将中缀表达式转换为前缀表达式
3、后缀表达式求值
算法
1、设置一个操作数栈opnd
2、从左到右扫描后缀表达式,直到遇到结束标志‘\0’
2.1如果读到的是操作数,那么就将其进行入栈
2.2如果读到的是运算符,那么就将栈顶的两个操作数出栈,后弹出的操作数为被操作数,先弹出的为操作数,将得到的操作数完成运算符所规定的运算,然后将结果入栈
2.3如果读到空格就跳过
3、表达式扫描完成之后,栈中就剩下一个数为表达式的值
4、栈与递归
1、汉诺塔问题
经典三步走:(假设有A、B、C三个柱子)
1、(n-1) A->C->B
//将n-1个盘子由A经过C移动到B
2、n A->C
//将第n个盘子由A移动到C
3、(n-1) B->A->C
//将n-1个盘子由B经过A移动到C
n个盘子最少移动次数:2^n-1
3 题目练习
n-i+1
top[1]+1=top[2]