主要内容 #
- 何为单链表的反转
- 迭代反转链表
- 参考代码
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;
    }
}