数据结构与算法之美【总结笔记】 -- 链表 - 如何写出正确链表代码

1.深入理解指针或者引用,java中为引用,即理解下面的话

将某个变量赋值给指针,实际上就是将这个变量的地址赋值给指针,或者反过来说,指针中存储了这个变量的内存地址,指向了这个变量的内存地址,指向了这个变量,通过这个指针就能找到这个变量。

2.警惕指针丢失和内存泄漏(c,c++)

在进行插入和删除的操作的时候,操作的都是指针,而指针又很抽象,代码不规范的话,极容易出现逻辑异常,指针丢失的情况,比如:针对下列操作的代码: p->next = x ; x->next = p-next; 原来p后面所有的节店全部丢失,java中会有GC进行清理,而C中,就会出现内存泄漏的情况。所以,一定要注意操作的顺序。

数据结构与算法之美【总结笔记】 -- 链表 - 如何写出正确链表代码_第1张图片

3.利用哨兵简化实现难度,在对链表的头尾节店进行插入和删除操作的时候,往往需要进行判空,可以在链表的头和尾分别各加一个哨兵结点,这样就不需要判空了,不仅简化了操作,还减少了出错的可能性。

哨兵可以理解为它可以减少特殊情况的判断,比如判空,比如判越界,比如减少链表插入删除中对空链表的判断,比如例子中对i越界的判断。

空与越界可以认为是小概率情况,所以代码每一次操作都走一遍判断,在大部分情况下都会是多余的。

哨兵的巧妙就是提前将这种情况去除,比如给一个哨兵结点,以及将key赋值给数组末元素,让数组遍历不用判断越界也可以因为相等停下来。

使用哨兵的指导思想应该是将小概率需要的判断先提前扼杀,比如提前给他一个值让他不为null,或者提前预设值,或者多态的时候提前给个空实现,然后在每一次操作中不必再判断以增加效率。

4.重点留意边界条件处理,写完链表代码之后,在能运行基本要求的基础上,在加几个用来检查是否真确的边界条件验证:

(1) 如果链表为空时,代码能否能正常工作?

(2)如果链表只包含一个节点时,代码是否能正常工作?

(3)如果链表只包含两个节点时,代码能否正常工作?

(4)代码逻辑在处理头结点和尾结点的时候,能否正常工作?

(5)集合不同环境,再思考一些,保证代码的健壮性。

5.举例画图,辅助思考,因为抽象和复杂的加持,只靠脑子想的话往往会很难受,可以借助画图举例的方法,减轻大脑的负担,专心于逻辑上的思考。

6.多写多练,将常见的链表操作多写几遍,学习优秀的解题方法,理解融会贯通成自己的,孰能生巧。

(1)链表反转

(2)链表中环的检测

(3)两个有序链表的合并

(4)删除链表倒数第n个节点

(5)求链表的中间节点

思考时间不要太长,先用第一时间想到的暴力法将问题解决掉,在学习那些牛逼方法,更能深入理解。

你可能感兴趣的:(数据结构与算法)