主要内容 #
- 何为单链表的反转
- 迭代反转链表
- 参考代码
1. 何为单链表的反转 #
通过前面章节的学习,读者已经对单链表以及它的用法有了一个完整的了解。在此基础上,本节再带领大家研究一个和单链表有关的问题,即如何实现单链表的反转。
反转链表,又可以称为翻转或逆置链表,它们表达的是同一个意思。以下图所示的链表为例:
经过反转(翻转、逆置)后,得到的新链表如下图所示:
通过对比两图中的链表不难得知,所谓反转链表,就是将链表整体“反过来”,将头变成尾、尾变成头。那么,如何实现链表的反转呢?
2. 迭代反转链表 #
该算法的实现思想非常直接,就是从当前链表的首元节点开始,一直遍历至链表的最后一个节点,这期间会逐个改变所遍历到的节点的指针域,另其指向前一个节点。
具体的实现方法也很简单,借助 3 个指针即可。以图1中建立的链表为例,首先我们定义 3 个指针并分别命名为 beg、mid、end。它们的初始指向如下图所示:
在上图的基础上,遍历链表的过程就等价为:3 个指针每次各向后移动一个节点,直至 mid 指向链表中最后一个节点(此时 end 为 NULL )。需要注意的是,这 3 个指针每移动之前,都需要做一步操作,即改变 mid 所指节点的指针域,另其指向和 beg 相同。
1) 在上图的基础上,我们先改变 mid 所指节点的指针域指向,另其和 beg 相同(即改为 NULL),然后再将 3 个指针整体各向后移动一个节点。整个过程如下图所示:
2) 在上图的基础上,先改变 mid 所指节点的指针域指向,另其和 beg 相同(指向节点 1 ),再将 3 个指针整体各向后移动一个节点。整个过程如下图所示:
3) 在上图基础上,先改变 mid 所指节点的指针域指向,另其和 beg 相同(指向节点 2 ),再将 3 个指针整体各向后移动一个节点。整个过程如下图所示:
4) 上中,虽然 mid 指向了原链表最后一个节点,但显然整个反转的操作还差一步,即需要最后修改一次 mid 所指节点的指针域指向,另其和 beg 相同(指向节点 3)。如下图所示:
注意,这里只需改变 mid 所指节点的指向即可,不用修改 3 个指针的指向。
5) 最后只需改变 head 头指针的指向,另其和 mid 同向,就实现了链表的反转。
3. 参考代码 #
//迭代反转法,head 为无头节点链表的头指针 link * iteration_reverse(link* head) { if (head == NULL || head->next == NULL) { return head; } else { link * beg = NULL; link * mid = head; link * end = head->next; //一直遍历 while (1) { //修改 mid 所指节点的指向 mid->next = beg; //此时判断 end 是否为 NULL,如果成立则退出循环 if (end == NULL) { break; } //整体向后移动 3 个指针 beg = mid; mid = end; end = end->next; } //最后修改 head 头指针的指向 head = mid; return head; } }