一、理解指针或引用的含义
-
含义:将某个变量(对象)赋值给指针(引用),实际上就是讲这个变量的地址赋值给指针
-
示例:
1)p->next = q;表示p节点的后继指针存储了q节点的内存地址
2)p->next = p->next->next;表示p节点的后继指存储了p节点的下下个节点的内存地址
二、警惕指针丢失和内存泄漏(单链表)
-
插入节点
1)在节点a和节点b之间插入节点x,b是a的下一个节点,p指针指向节点a,则造成指针丢失和内存泄漏的代码:p->next = x; x->next = p->next; 显然这会导致x节点的后继指针指向自身
2)正确的写法是2句代码交换顺序,即: x->next = p->next; p->next = x; -
删除节点
在节点a和节点b之间删除节点b,b是a的写一个节点,p指针指向节点a:p->next = p->next->next;
三、重点留意边界条件处理
经常用来检查链表是否正确的边界4个边界条件:
- 如果链表为空时,代码是否能正常工作?
- 如果链表只包含一个节点时,代码是否能正常工作?
- 如果链表质保函两个节点时,代码是否能正常工作?
- 代码逻辑在处理头尾节点时,代码是否能正常工作?
四、5个常见的链表操作
- 单链表反转
- 链表中环的检测
- 两个有序链表合并
- 删除链表倒数第n个节点
- 求链表的中间节点
五、“哨兵”简化编程
利用哨兵简化编程难度的技巧,在很多代码中都有用到,比如:插入排序、归并排序、动态规划等。查看下面两段代码的差距。
未引入哨兵的情况
如果在p节点后插入一个节点,只需要2行代码即可搞定:
new_node->next = p->next;
p->next = new_node;
但,若向空链表中插入一个节点,则代码如下:
if(head == null) {
head = new_node;
}
如果想要删除节点p的后继节点ÿ