目录
四、栈和队列
栈(stack):只能最末尾进行插入和删除,先进后出,后进先出(last in first out,LIFO结构)。
允许插入删除的是栈顶,另一端栈底。操作称为入栈(push)出栈(pop)。
4.5两栈共享空间
使用数组实现,两栈分别从两端开始向中间拓展。适用于两种一增一减的情况。
4.6栈的链式存储
这个是很少见的知识点。
链表的头部,是栈顶,进行插入/删除。
进栈:将当前链表赋给新的next。
出栈:当前的next 是新的链表。
4.8栈的应用:递归
斐波那契数列:可以用迭代/递归实现
迭代使用循环结构,递归使用选择结构。递归使程序的结构更清晰,简洁,容易理解。但会建立函数副本,耗费大量时间和内存。
递归的时间就是先把上一层的临时变量压入栈。
4.9 栈的应用:四则运算
有加减乘除和括号的运算,遇到左括号就进栈,出现右括号出栈。
中缀表达式:9+(3-1)*3+10/2
后缀表达法:931-3×+10 2 /+,符号出现在运算数字的后面。也称为逆波兰(Reverse Polish Notation,RPN)表示
计算方式:遇到数字进栈,遇到符号,将栈顶的两个数字出栈进行运算,运算结果进栈。
中缀如何转后缀:遇到数字,输出;遇到符号,优先级大于栈顶,压栈,否则是小于等于或者右括号,栈顶元素出栈,当前符号进栈。括号有匹配的问题。
4.10 队列
队列(queue)只允许在一段进行插入,另一端进行删除的线性表。先进先出(First In First out , FIFO)
插入一端称为队尾,允许删除的叫队头。
4.12循环队列
顺序存储:
插入O(1)
删除O(n),整体前移。如果不前移,O(1),但是会出现“假溢出”,前面空着,后面满了,无法插入。
就引出了循环队列,即数组尾接数组头,但存在数组溢出的问题。
4.13 队列的链式存储
链队列:尾进头出的链队列,两个指针分别指向链表头部和尾部。
入队操作:链表尾部插入节点
出队操作:链表头部节点出队
时间复杂度均为O(1)
总结:可以确定队列最大长度时,使用循环队列;无法确定长度时,使用链队列。
五、字符串
5.2定义
串string是由零个或多个字符组成的有限序列,又称字符串。
两个字符串的大小(字典序):
从第一位开始,ASCII值小的更小,相同时,找下一位。
5.5 字符串的存储结构
1.顺序存储结构:数组的长度不好确定;
2.链式存储结构:
一个节点一个字符:太占用空间
一个节点n个字符,不足的#或其他字符补足:n的选择很重要
综合来说,顺序存储更适合字符串。
5.6 模式匹配算法
在一个长的字符串中,定位子串的位置。
例如在"goodgoogle"中找到"google"。
最坏时间复杂度是,O(m*n),m,n为两个字符串长度。因为可能前几位都一样,例如"00000001"
中找"0001"。每一次都需要遍历到最后。
5.7 KMP模式匹配
字符相同/不同的情况。
#M,回头看懂了再整理