这样代码就会显得很繁琐,所以引入“哨兵”节点来解决这个问题。
3.引入“哨兵”的情况
“哨兵”节点不存储数据,无论链表是否为空,head指针都会指向它,作为链表的头结点始终存在。这样,插入第一个节点和插入其他节点,删除最后一个节点和删除其他节点都可以统一为相同的代码实现逻辑了。
4.“哨兵”还有哪些应用场景?
1.
2. 如扫雷游戏
每次点击一个格子就要扫描相邻的8个格子。当点击到边界的时候,相邻不足8个格子,这时候就可以在设计游戏的时候为边界外圈加上隐藏的一层格子。这样就可以使所有的操作一致化,不需要对边界的条件作出特殊的处理。
总结:
1 ) 哨兵基本不能降低数据结构相关操作的渐近时间界,但其可以降低常数因子。
2 ) 哨兵的设计可以使得代码更简洁,可以省去一些由于边界环境不同而作出的特殊处理。
3 ) 在某些情况下哨兵可以使得循环语句更紧凑,降低运行时间里n或者n²项的系数。
4 ) 慎用:哨兵会占用额外的内存。当使用哨兵的开销较大时,有可能会造成严重的浪费
重点留意边界条件处理
经常用来检查链表是否正确的边界4个边界条件:
1.如果链表为空时,代码是否能正常工作?
2.如果链表只包含一个节点时,代码是否能正常工作?
3.如果链表只包含两个节点时,代码是否能正常工作?
4.代码逻辑在处理头尾节点时是否能正常工作?
举例画图,辅助思考
核心思想:释放脑容量,留更多的给逻辑思考,这样就会感觉到思路清晰很多。
多写多练,没有捷径
5个常见的链表操作:
1.单链表反转
2.链表中环的检测
3.两个有序链表合并
4.删除链表倒数第n个节点
5.求链表的中间节点