如何轻松写出正确的链表代码
本文创作灵感来源于 极客时间 王争老师的《数据结构与算法之美》课程,通过课后反思以及借鉴各位学友的发言总结,现整理出自己的知识架构,以便日后温故知新,查漏补缺。
理解了链表的基础知识,但是距离写出正确的链表代码还是有一段差距的,这个差距就需要我们反复练习,总结,归纳,再练习。王争老师提供了以下几点技巧,帮助我们迅速提高自己写出正确链表代码的动手能力。
理解指针或者引用的正确含义
- 在C语言中有着指针的概念。所谓指针,可以理解成是一个特殊的变量,存储的不是具体的数值,而是内存地址。通常所说的指针指向 p ,就是说这个指针存储的是变量 p 的内存地址。在高级语言中,抛弃了指针的概念,转而用引用这个概念代替指针的作用。
警惕指针丢失和内存泄漏
- 链表中插入节点的时候,一定要注意指针的指向顺序。比如在 a ,b两个节点之间插入节点 n ,指针丢失的写法就是:a->next = n,n->next = a->next。再插入节点之前,a->next = b,但是按照上面的写法,直接a->next = n。这样直接导致链表失去了访问节点 b 内存地址的指针,n 节点后面无法跟上 b 节点,这就导致了指针丢失。
- 在链表中删除节点的时候,一定要注意内存的释放。比如在 a,n,b三个节点中删除节点 n,内存泄漏的写法就是:a->next = n->next。这样,a 节点的后继指针指向了 b 节点,但是没有执行 n->next = null,就导致了删除节点依然指向 b 节点的内存地址,是的内存泄漏。
利用哨兵简化实现难度
- 引入哨兵的概念,简化代码的实行过程。王争老师举了一个例子:遍历一个数组,我们找出值等于 5 的元素的下标。常规写法,我们会利用for循环遍历数组,然后针对每一次循环都做一次当前元素是否等于 5 。当我们引入哨兵的概念时,获取数组最后一个元素,先做一次判断是否等于 5 ,如果不等于 5 ,我们创建一个变量(哨兵变量),该变量存储数组最后一个元素的值,另数组的最后一个元素值为 5 。对数组遍历,使用 while 循环,循环条件就是当前数组元素不等于 5 ,这样循环内部就少了一次值得对比,简化了代码操作。
- 代码如下
1
2
3
4
5
6
7
8
9
10
11
12int[] list = new int[10];
int node = list[10];
if(node == 5){
return -1;
}
list[10] = 5;
int i = 0;
while(list[i] != 5){
i++;
}
list[10] = node;
return i;