单链表反转
前几天做题遇到了链表反转的问题,即剑指offer06和24,涉及到了链表反转的知识。奈何本人太菜,早已忘了数据结构课本中链表反转的具体操作,这里记录并复习一下有关单向链表反转的几种方法。
参考链接:单链表反转详解
定义
链表节点定义如下(python):
1 |
|
原链表:1->2->3->4->5->NULL
反转后:5->4->3->2->1->NULL
新建链表法
新建链表法的主要思想是新建一个链表,保证其与原链表顺序相反,然后返回新链表,实现原链表的反转。新建反转链表有两种方法,一种是使用头插法新建链表,另一种是使用辅助栈(或者数组等)。这类方法的主要特点是需要使用额外的存储空间。
头插法
使用头插法新建一个链表(虽说是新链表,只是换了个头指针,但没有使用新的存储空间),每次将新节点插入到新链表头节点之后,然后返回新链表实现反转。
1 |
|
- 时间复杂度:遍历链表使用线性大小空间。
- 空间复杂度:只需要两个额外的指针,没有额外使用存储空间
辅助栈新建链表
第二种方式是使用辅助栈的方法,将原链表依次入栈,然后新建链表,将栈中的元素依次出栈作为新链表的下一个节点,则新链表即为原链表的反转链表。
1 |
|
- 时间复杂度:遍历链表使用线性大小空间。
- 空间复杂度:额外辅助空间和新建链表的存储空间,均为线性大小。
迭代遍历法(双指针)
迭代反转法(原地反转法),从当前链表的头结点开始,一直遍历到链表的最后一个节点,期间逐个改变节点指针的方向,使其指向前一个节点,返回最后一个位置的指针(或者说将头指针指向最后一个位置)。参考链接
1 |
|
- 时间复杂度:遍历链表使用线性大小空间。
- 空间复杂度:变量
pre
和cur
使用常数大小额外空间。
就地逆置法
就地逆置法(也叫头插法),与头插法新建链表类似,不同的是不需要新链表,只需要用两个指针对原链表本身进行操作,将每个节点依次插入到头节点后面,最后返回头节点。
1 |
|
此方法和上面提到的头插法大同小异,一个是返回原来的头指针,一个是返回新指针。此方法中的原链表头指针不动,上面的头插法的原链表头指针是移动的。
这两种方法都可以叫做头插法。
- 时间复杂度:遍历链表使用线性大小空间。
- 空间复杂度:变量
pre
和cur
使用常数大小额外空间。
递归法
递归法的思想是递归到停止条件,即链尾,然后逐层返回递归结果(从后向前将链表的指向反向)。
1 |
|
- 时间复杂度:一遍递归深入并返回
- 空间复杂度:不需要额外空间,只需要两个指针(但迭代过程需要一直创建/释放)
这递归太难理解了 :-( ,建议看大佬题解剑指offer24题解或者单链表反转详解。
- 本文作者:Kangshitao
- 本文链接:http://kangshitao.github.io/2020/12/05/reverse-linkedlist/index.html
- 版权声明:本博客所有文章均采用 BY-NC-SA 许可协议,转载请注明出处!