7、链表(下):如何轻松写出正确的链表代码?

很汗颜,现在让自己完整的写出一个简单的链表结构竟然会无法动笔,作为一个程序猿,需要修行的路还很长。

技巧一:理解指针或引用的含义

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

例子: p->next = q。这行代码的意思是p节点的next指针存储了q节点的内存地址。

        同理, p->next = p->next->next。这行代码的意思是p节点的next指针存储了p节点的下下一个节点的地址。

技巧二:警惕指针丢失和内存泄漏

举例插入节点:

如图所示,我们希望在节点a和b之间插入节点x,假设当前指针p指向节点a。如果代码如下就会发生指针丢失和内存泄漏。

p->next = x;
x->next = p->next; 

此处在p->next执行之后,其指针就不再指向b了,而是指向x。第二行代码就相当于自己指向了自己。因此,链表断成了两半,从节点b往后的所有界定啊都无法访问。

正确方式:将第一行代码和第二行代码颠倒顺序,就ok了。

技巧三:利用哨兵简化实现难度

如下,节点p之后插入节点的正确代码。

x->next = p->next;
p->next = x;

注意:当需要向一个空链表中插入第一个节点,上面的逻辑就不能用了。正确答案如下:

if(head==null){
    head = new_node;
}

同理,在编写链表的删除操作之时,分为两种情况:

第一种,删除节点不是尾节点,而是p节点的后继结点

p->next = p->next->next;

第二种,删除结点是尾结点

if(node->next == null){
   head = null;  
}

 技巧四:重点留意边界条件处理

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

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

如果链表只包含两个结点时,代码是否能正常工作?

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

技巧五:自己画图,辅助记忆

常见的链表操作:

一、单链表反转

二、链表中环的检测

三、两个有序的链表的合并

四、删除链表倒数第n个结点

五、求链表的中间结点

分别对应LeetCode练习题编号:206,141,21,19,876。

课后思考:你是否能想到其他场景,利用哨兵可以大大简化编码难度?

后续把自己实现的五种链表操作传上来。欢迎指正!

posted @ 2018-10-14 17:52  十月要努力丫  阅读(386)  评论(1编辑  收藏  举报