在第一章,了解了线性表的基础知识,线性表是线性结构的一种类型,线性结构是从逻辑结构的角度出发,相邻的元素是一对一的关系,今天将完成另外的线性结构的学习:栈、队列、串
**栈:**只允许在线性表的一端进行插入和删除,先进栈的元素后出栈(先进后出),插入删除的那端是栈顶,不允许执行任何操作的是栈底
**队列:**只允许在线性表的一端进行插入,另外一端进行删除,先入队的元素将先出队(先进先出),入队的那端是队首(front),出队的那端是队尾(rear)
rear一直都是指向空的 ,front一直指向队首元素
进队时front在移动,出队时 rear在移动
共享栈:两个栈共享一段存储空间
循环队列
也是单独拿出一个单元来存放队尾指针,这样就能够判断是否是队空
循环队列 front和rear的数值:
队列满:front==(rear+1)%maxsize
队列空:front==rear
入队:队尾 rear=(rear+1)%maxsize
出队:队头front=(front+1)%maxsize
队内个数:(rear-front+maxsize)%maxsize
栈的应用:
1.函数调用,保留现场必须要用到栈
比如说函数的嵌套调用:
void main()
{
int a;
fun(a);
}
void fun(int a)
{
int b;
fun1(b)
}
void fun1(int b)
{
return;
}
在主函数中执行时,要调用fun函数,而fun函数又要调用fun1函数,所以最开始执行的就是fun1函数,fun1函数执行完之后再执行fun函数,最后主函数结束,明明fun1函数是最后调用,可是是最开始执行的,这就很符合栈的先进后出特性。
2.括号的匹配
(【】)这样就是匹配的括号
())这样就是不匹配的括号
进行括号的匹配判断:
1.扫描输入的字符串,如果是左括号,则入栈
2.如果是右括号,则判断栈是否为空,如果为空,则说明不匹配,如果不为空,则看此时栈顶元素是否与这个右括号匹配,如果匹配,则继续进行下一次扫描,如果不匹配,则说明这个括号不匹配,结束
3.左右括号都判断完后,假设左括号全部进栈完毕,右括号扫描后,全部匹配出栈完毕,此时还要判断整个栈是否为空,如果不为空,则还有未匹配的左括号,此时也说明这不是正确的括号匹配
串:
串依旧是一种线性表,只不过是一种非常特殊的线性表,特殊在每个元素的字符类型都只能是字符型。
串的模式匹配,KMP算法用来判断子串是否在串中出现
递归问题:
递归调用:当一个函数在他的函数体内直接或者间接的调用自身,就形成了递归调用。
递归调用有:递归体和递归出口
经典问题:汉诺塔问题
汉诺塔详解