单链表倒置可以说是面试中提问率最高的题目了。网上有很多单链表倒置的算法,但是实现解释的不是很清晰。总结了一些算法之后,把我自己认为好理解的简单方便的算法整理下来,方便以后自己复习。
1.迭代
下面的代码及注释应该很好的解释了头插法来实现单链表倒置的思路。
1 Node* Reverse(Node* node) 2 { 3 Node* prev = NULL; // 用于保存当前链表的头结点
4 Node* tmp = NULL; // 用于保存当前节点的next
5 while (node != NULL) 6 { 7 tmp = node->_next; // 保存当前节点的next
8
9 node->_next = prev; // 将当前节点插入到头结点前
10 prev = node; // 插入之后将当前节点设置为头节点
11
12 node = tmp; // next为下次迭代的当前节点
13 } 14 return prev; // 循环结束后,p即为倒置后的头结点
15 }
2.递归
递归来实现倒置最直接的描述就是入栈出栈,链表节点从头结点开始依次入栈,最后到尾节点入栈结束;开始出栈:尾节点最先出栈,出栈时依次将两个相邻的节点交换指向;出栈结束后,整个链表的倒置就完成了。重要的地方是将最先出栈的尾节点返回,这就是倒置后的链表的头结点。
1 Node* Reverse_recursive(Node* node) 2 { 3 // 停止条件
4 if (node->_next == NULL) 5 return node; // 表示到最后一个节点,返回这个节点当作头结点 6
7 // 递归
8 Node* prev = Reverse_recursive(node->_next); 9
10 // 操作
11 Node* tmp = node->_next; // 保存当前节点next
12 tmp->_next = node; // 将当前节点放到其next之后
13 node->_next = NULL; // 将当前节点的next置为NULL
14
15 return prev; 16 }