链表的翻转
来源:互联网 发布:anaconda for mac 编辑:程序博客网 时间:2024/06/01 08:12
链表的翻转
链表的翻转分为部分翻转和全部翻转。本文,实现了一种通用的链表翻转程序,其时间复杂度为n。
链表如下:
程序中包含如下类:
1、Node类,即链表的节点,节点中只有一个属性iData;
class Node { public int iData; Node nextNode = null; public Node(int iData) { this.iData = iData; }}
2、链表类,链表类中仅实现了插入和打印链表的方法,并且链表具有表头节点root具体如下:
class Link { public Node root = null; public void insert(int iData) { Node newNode = new Node(iData); if (root == null) { root = newNode; } else { Node current = root; Node pre = root; while (current != null) { pre = current; current = current.nextNode; } pre.nextNode = newNode; } } public void display() { Node current = root; while (current != null) { System.out.print(current.iData + " "); current = current.nextNode; } System.out.println(); }}
3、翻转链表的实现
链表从0开始计数,例如要翻转1到4中的元素(包含边界节点),那么输出应该是:
如果链表要翻转0到7的所有元素输出应该是
采用头插法,定义三个指针(这里只java的引用,因为类似c语言中的指针,因此这里借用指针之一概念,但是java里面是没有指针概念的),
pre:用来指向要翻转的节点的前一个节点,例如当要翻转1到4节点时,pre指向第0个节点
current:用来指向需要操作的节点
next:用来指向原链表中的下一个要操作的节点
tmp:指向第一个要操作的节点,当全部的节点翻转完后该节点需要链上剩余的节点(没有被要求翻转的节点),例如当要翻转1到4节点时tmp指向的是第一个节点。
翻转n到m节点,翻转的过程,以翻转1到4节点为例(n=1,m=4),
首先链表的pre空转0步(空转就是pre遍历沿着节点向下走,什么也不做,空转是为了将pre指向需要翻转的节点之前的节点这里时节点0)使pre指向0号节点,从该节点的下一个节点开始翻转;然后将current指向pre节点的下一个节点,接下来需要断开current在原链表中所指向的下一个节点,在断开之前需要将next节点指向current的下一个节点即current.nextNode节点,因此next指向current的下一个节点;然后将current节点的从原链表中断掉,使current的下一个节点(current.netNode)指向pre的下一个节点(pre.nextNode);断掉pre的下一个节点pre.nextNode的原指向,使pre.nextNode指向current节点,这样第一次翻转成功(注意当执行第一次翻转的时候会发现pre.nextNode和current是同一个节点,因此第一次会使current的下一个节点指向自身)。然后将current从新指向next节点。重复步骤直到翻转了n-m次;最后将剩下的不需要翻转的节点链上,当循环结束后next保存的就是剩下的第一个不需要翻转的节点,而如前所述tmp保存的是第一个被翻转的节点,因此将tmp.nextNode指向next节点。
如图:
将操作步骤罗列如下:
(1)、链表的pre空转0步使pre指向0号节点;
(2)、将current指向pre节点的下一个节点;
(3)、将next节点指向current的下一个节点 ;
(4)、断开current在原链表中所指向的下一个节点;
(5)、将current的下一个节点指向pre节点的下一个节点;
(6)、断掉pre的下一个节点pre.nextNode的原指向,使pre.nextNode指向current节点;
(7)、将current指向next指向的节点;
(8)、重复步骤3到7,指导翻转了n-m次;
(9)、将tmp.nextNode指向next节点。
注意:当从节点0开始翻转时,上面的步骤需要适当的修改,因为当需要从0号节点开始翻转时,pre是 无法指向0节点之前的节点的,因此如果需要从0 号开始翻转,可以在链表的头部加一个节点,然后在进行翻转,在翻转完成后将链表的root节点从新指向pre.nextNode即可。
翻转操作的代码:
public class LinkFlip { public static void main(String[] args) { Link myLink = new Link(); myLink.insert(0); myLink.insert(1); myLink.insert(2); myLink.insert(3); myLink.insert(4); myLink.insert(5); myLink.insert(6); myLink.insert(7); flip(myLink, 0, 7); myLink.display(); } public static void flip(Link mylink, int m, int n) { Node pre = mylink.root; Node current = mylink.root; Node next = mylink.root; Node tmp = null; if (m == 0) { pre = new Node(-1); pre.nextNode = mylink.root; } else { for (int i = 0; i < m - 1; i++) { pre = pre.nextNode; } } current = pre.nextNode; tmp = current; pre.nextNode = null; for (int i = 0; i <= (n - m); i++) { next = current.nextNode; current.nextNode = pre.nextNode; System.out.println(current.iData); pre.nextNode = current; current = next; } if (m == 0) { mylink.root = pre.nextNode; } tmp.nextNode = next; }}
写了个更简单的
public ListNode ReverseList(ListNode head) { ListNode pre = null; ListNode current = head; ListNode next = null; while(current!=null){ next = current.next; current.next = pre; pre= current; current = next; } return pre; }
- 无情链表的创建,,翻转翻转
- 链表的翻转
- 链表的翻转
- 链表的翻转
- 链表的翻转实现
- 链表的部分翻转
- 链表的部分翻转
- 链表的部分翻转
- 链表的相邻元素的翻转
- 单向链表的创建及翻转
- 普通单向链表的翻转
- 链表的翻转合并创建
- 翻转链表的C++实现
- 链表的翻转(史上最简)
- Java-链表的部分翻转
- 算法学习-链表的部分翻转
- 链表翻转----逆置链表的变形
- 算法<翻转链表的指定区间>
- csv 文件的创建
- 关于Tomcat脚本启动闪退问题
- 蓝桥杯 Java 入门训练 圆的面积
- Unreal Engin_画廊制作笔记 _008<灯光处理,夜晚的画廊灯光设置>
- hdu 5334
- 链表的翻转
- CNN的反向传播推导与理解
- [编程题] 寻找三角形
- C语言学习历程——Training01整数算法训练05
- Android屏幕ldpi,mdpi,hdpi,xhdpi,xxhdpi的关系
- 翱旗科技发布四款新品,欲打造产品化、通用化DT服务
- BZOJ 1008 [HNOI2008]越狱
- 蓝桥杯 入门训练 Fibonacci数列 Java
- 文章标题 Markdown使用