Reverse Linked List II 单向链表逆序(部分逆序)
2015-03-24 20:48
218 查看
0 问题描述
原题点击这里。
将单向链表第m个位置到第n个位置倒序连接。例如,
原链表:1->2->3->4->5, m=2, n =4
新链表:1->4->3->2->1
(注:最终的新链表记为head,过程中临时使用的一个链表头记为h)
1 基本思路
首先考虑整个链表的情况。见到单向链表的第一反应自然是轮询链表head中每个节点,轮询过程中按需要建立一个新链表h,每次访问一个节点,就将这个节点放在前一个访问的节点之后,这样便实现了倒序。
然后再考虑部分倒序。要部分倒序,便要找出这部分从哪里开始,从哪里结束,根据前面的方法将该部分倒序之后,将倒序后的部分链表链上其他部分。
2 单向链表逆序
假设有三个节点,其过程如图(1)所示。
第一步取出node1,新链头指向node1,node1->next指向空,其他部分不变;
第二步取出node2,新链头指向node2,node2->next指向前一个访问的节点(即node1);
第二步取出node3,新链头指向node3,node3->next指向前一个访问的节点(即node2);
从这个过程中可以看到几点:
这是一个循环过程。循环的次数=链表中节点的个数。
每个节点都访问了且只访问一次,因而时间复杂度是O(n)。
需要三个辅助变量。1、使用了一个临时链头h;2、观察第二步(图1-2),该步将node2->next指向了node1,因此需要使用变量(prev)将node1保存下来。3、同样观察第二步,该步中将node2和node3之间的联系断开了,但是在下一次操作中需要使用到node3,因此需要使用变量(next)将node3保存下来。
这部分也就是该问题的核心代码。
![](http://images.cnitblog.com/blog2015/442992/201503/242047569422288.png)
3 部分逆序
假设现在有五个节点,我们需要将节点1-3倒序。首先将1-3倒序,那么现在该如何将节点0、4和完成倒序后的链表连接起来?结合图容易想到,node0->next应指向node3;node1->next应指向node4(见图2-2)。
node0->next指向node3只需要将新链表头h赋给它;
node1->next指向node4需要在上一节第一步中将它指向node4.
图示采用的是一个特例,在一般情况下,我们需要找到pa->next连接新链表头h的pa,以及新链表尾部->next指向的pb(见图2-3)。寻找很简单,但必须要考虑特殊情况:如果m=1,即h就是我们最后需要得到的链表头head.
![](http://images.cnitblog.com/blog2015/442992/201503/242048127086270.png)
4 源代码
ReverseLinkedListII.c Github
原题点击这里。
将单向链表第m个位置到第n个位置倒序连接。例如,
原链表:1->2->3->4->5, m=2, n =4
新链表:1->4->3->2->1
(注:最终的新链表记为head,过程中临时使用的一个链表头记为h)
1 基本思路
首先考虑整个链表的情况。见到单向链表的第一反应自然是轮询链表head中每个节点,轮询过程中按需要建立一个新链表h,每次访问一个节点,就将这个节点放在前一个访问的节点之后,这样便实现了倒序。
然后再考虑部分倒序。要部分倒序,便要找出这部分从哪里开始,从哪里结束,根据前面的方法将该部分倒序之后,将倒序后的部分链表链上其他部分。
2 单向链表逆序
假设有三个节点,其过程如图(1)所示。
第一步取出node1,新链头指向node1,node1->next指向空,其他部分不变;
第二步取出node2,新链头指向node2,node2->next指向前一个访问的节点(即node1);
第二步取出node3,新链头指向node3,node3->next指向前一个访问的节点(即node2);
从这个过程中可以看到几点:
这是一个循环过程。循环的次数=链表中节点的个数。
每个节点都访问了且只访问一次,因而时间复杂度是O(n)。
需要三个辅助变量。1、使用了一个临时链头h;2、观察第二步(图1-2),该步将node2->next指向了node1,因此需要使用变量(prev)将node1保存下来。3、同样观察第二步,该步中将node2和node3之间的联系断开了,但是在下一次操作中需要使用到node3,因此需要使用变量(next)将node3保存下来。
这部分也就是该问题的核心代码。
while (len--) { next = p->next; h = p; h->next = prev; prev = p; p = next; }
![](http://images.cnitblog.com/blog2015/442992/201503/242047569422288.png)
3 部分逆序
假设现在有五个节点,我们需要将节点1-3倒序。首先将1-3倒序,那么现在该如何将节点0、4和完成倒序后的链表连接起来?结合图容易想到,node0->next应指向node3;node1->next应指向node4(见图2-2)。
node0->next指向node3只需要将新链表头h赋给它;
node1->next指向node4需要在上一节第一步中将它指向node4.
图示采用的是一个特例,在一般情况下,我们需要找到pa->next连接新链表头h的pa,以及新链表尾部->next指向的pb(见图2-3)。寻找很简单,但必须要考虑特殊情况:如果m=1,即h就是我们最后需要得到的链表头head.
![](http://images.cnitblog.com/blog2015/442992/201503/242048127086270.png)
4 源代码
ReverseLinkedListII.c Github
相关文章推荐
- 单向链表逆序输出
- 单向链表逆序
- 《C算法》读书笔记(5):单向链表逆序
- 【数据结构练习】单向链表实现、链表逆序实现
- 将单向链表逆序
- 关于单向链表的逆序
- 单向链表的逆序,不使用额外节点存储实现
- 单向链表逆序
- C语言数据结构(链表)单向链表的创建删除逆序
- 单向链表逆序
- 两个单向链表(表长不等)后半部分重合,怎么找到开始重合的那个节点
- 单向链表的逆序操作
- 单向链表每k个数逆序拼接
- 用单向链表输入数据,逆序显示出
- 反转部分单向链表 Python 版
- 单向链表之逆序(C语言实现)
- C/c++语言,求单向链表的逆序_普通方法_header+p+q工作指针
- 反转部分单向链表
- 两种方法实现单向链表的创建、遍历、删除、查找、逆序输出(循环法和递归法)
- 算法题18 逆序(字符串、整数、单向链表)