“链表反转”这几行代码写对的人不足10%。
技巧一:理解指针或引用的含义事实上,
和指针混在一起变难。没有指针语言,引用 取代,意思一样:存储所指对象内存地址
变量(实际上变量地址)赋值给指针,反过来说,指针存变量内存地址,通过指针找到变量
p->next=q。p结点中next指针存储了q内存地址。
p->next=p->next->next。p的next指针存p下下个结点内存地址。
技巧二:警惕指针丢失和内存泄漏
希望结点a、b之间插入结点x,假设p指向结点a。指针丢失和内存泄露:
1、2行代码顺序应颠倒。删除也一定手动释放内存空间,否则,也会出现内存泄漏的问题。Java虚拟机自动管理内存不需
技巧三:利用哨兵简化实现难度
p后面插入新结点:new_node->next = p->next; p->next = new_node;
向空链表插入第一个结点 if (head == null) { head = new_node; }
删除p的后继结点:p->next = p->next->next;
删除最后一个结点,if (head->next == null) { head = null; }
哨兵解决第一个和最后节点特殊情况:增加head指针(哨兵结点不存数据),叫带头链表
哨兵简化编程,如插入排序、归并排序、动态规划等。
技巧四:重点留意边界条件处理
链表空、一个结点、头结点和尾结点的时候,代码是否能正常工作?
技巧五:举例画图,辅助思考
脑容量举例法和画图法。
技巧六:多写多练,没有捷径
单链表反转
链表中环的检测
两个有序的链表合并
删除链表倒数第n个结点
求链表的中间结点