数据结构—链表(三)
来源:互联网 发布:淘宝手机版店招制作 编辑:程序博客网 时间:2024/06/01 07:56
主要内容:
检测链表是否有环、在不知道头指针的情况下怎么删除非末尾节点、判断两个链表是否相交、找到相交链表的交点。
重点是看懂解题思路,思路明白了,代码就非常好写了。
package com.sf.linkedlist;/** * Created by laxe on 2016/12/1. */public class LinkedListDemo2 { static Node head=null; public static void main(String args[]) { head = new Node(1); Node next1 = new Node(2); Node next2 = new Node(3); Node next3 = new Node(4); Node next4 = new Node(5); Node next5 = new Node(6); Node next6 = new Node(7); head.next = next1; next1.next = next2; next2.next = next3; next3.next = next4; next4.next = next5; next5.next=next6; //next6.next=next3; showList(head); //System.out.println(isLoop()); //Node port=findLoopPort(); //System.out.print(port.val); deleteNode(next1); showList(head); }//检测一个链表是否有环 /** * 思路:设置两个指针,慢指针每次走一步,快指针每次走两步。 * 二者同时走,每次走完都比较一下是否相等,相等就代表这个链表是带环的单向链表。 * * * */ public static boolean isLoop(){ Node fast=head; Node slow=head; if(fast==null) return false; while(fast!=null && fast.next!=null){ fast=fast.next.next; slow=slow.next; if(fast==slow){ return true; } } return !(fast==null || fast.next==null); }//找到带环单链表的入口点 /** * 思路:在上个算法的基础上, * 找到快慢指针的相遇点为node,链表起始点为head, * head和node每次同时前进一步,二者相遇点即为环的入口点。 * 其实理解起来有点困难,可以尝试自己画图理解一下 * */ public static Node findLoopPort(){ Node fast=head; Node slow=head; if(fast==null) return null; Node meet=null;//快慢指针相遇点 while(fast!=null && fast.next!=null){ fast=fast.next.next; slow=slow.next; if(fast==slow) { meet = slow; break; } } if(fast==null || fast.next==null) return null; Node start=head; while(start!=meet){ start=start.next; meet=meet.next; } return meet; }//在不知道头指针的情况下删除指定节点 /** * 若待删除的节点为链表尾节点,那么无法删除,因为删除后无法使前驱结点的next指向null; * 若待删除的节点不是链表尾节点,那么可以通过交换这个节点与其后继节点的值,然后删除后继结点。 * * */ public static void deleteNode(Node node){ if(node==null || node.next==null) return; int temp=node.val; node.val=node.next.val; node.next.val=temp; node.next=node.next.next; }//如何判断两个链表是否相交 /** * 如果两个链表相交,那么他们一定有相同的尾节点。 * 思路:分别遍历两个链表,记录他们的尾节点,如果他们的尾节点相同,那么两个链表相交,否则不相交。 * * */ public static boolean isIntersect(Node h1,Node h2){ if(h1==null || h2==null) return false; Node t1=h1; Node t2=h2; while(t1!=null){ t1=t1.next; } while(t2!=null){ t2=t2.next; } return t1==t2; } /** * 如果两个链表相交,如何找到他们交响的第一个节点呢 * 思路:首先分别计算两个链表的长度len1,len2(假设了len1>len2), * 接着先对链表head1遍历(len1-len2)个节点到节点p,此时节点p与head2到他们相交的距离相等,此时同时遍历两个链表 * 直到遇到相同的节点为止,这个节点就是他们相交的节点。 * 需要注意,在找相交点之前,需要先判断两个链表是否相交,相交再去找相交点。 * */ public static Node getFirstMeetNode(Node h1,Node h2){ if(h1==null || h2==null) return null; Node t1=h1; Node t2=h2; int len1=0; int len2=0; while(t1!=null){ t1=t1.next; len1++; } while(t2!=null){ t2=t2.next; len2++; } if(t1!=t2) return null; Node r1=h1; Node r2=h2; if(len1>len2){ int d=len1-len2; while(d!=0){//找到解题思路中说到的“p” r1=r1.next; d--; } } if(len1<len2){ int d=len2-len1; while(d!=0){//找到解题思路中说到的“p” r2=r2.next; d--; } } while(r1!=r2){ r1=r1.next; r2=r2.next; } return r1; } /** * 打印链表 * */ public static void showList(Node head){ if(head==null) return; Node tmp=head; while(tmp!=null) { if(tmp.next!=null) { System.out.print(tmp.val+"->"); tmp = tmp.next; }else{ System.out.print(tmp.val); tmp = tmp.next; } } System.out.println(); } /** * 获取链表的长度 * */ public static int length(){ int length=0; Node tmp=head; while(tmp!=null){ length++; tmp=tmp.next; } return length; }}
0 0
- 数据结构—链表(三)
- 数据结构系列(三)链表
- 数据结构(1)—— 数据结构的三大结构
- 算法导论(三)——数据结构
- 数据结构——线性表(三)
- 数据结构——排序(三)
- java数据结构(三)——队列
- C++数据结构(三)——队列
- Lua数据结构 — Table(三)
- Lua数据结构 — Table(三)
- 数据结构——三
- 数据结构(三)
- (三)CvSeq数据结构
- 数据结构复习题(三)
- 数据结构(三):图
- 数据结构(三)
- 数据结构基础知识(三)
- 数据结构:(三)栈
- NumPy之二:数组形状操作
- 图像处理与计算机视觉基础,经典以及最近发展
- Linux I2C驱动个人理解(二)
- spring cloud微服务框架 第四天
- 移动端input上传调用相机
- 数据结构—链表(三)
- 类继承学习笔记
- linux 让history显示时间
- 正则表达式
- REST学习(二)
- ViewPager设置切换动画
- Java bean 是个什么概念?
- spring cloud微服务框架第五天
- MongoDB 数据导出mongoexport