java对链表(环、交叉链表的应用)
来源:互联网 发布:java人机猜拳代码 编辑:程序博客网 时间:2024/06/05 18:04
在链表中,有环链表,交叉链表,返回倒数第k个节点可谓非常经典,所以对java的实现做总结如下:
1、首先定义一个链表节点的类Node;
class Node{ int value; Node next; public Node(){ this(0);//注意调用时必须处在构造方法的第一行 } public Node(int val){ this.value=val; this.next=null; }}
2、在类LinkList中实现链表的头插创建 ,判环,求倒数第K个节点,以及判断两链表是否相交
class LinkList{ Node head; public LinkList(){ this.head=new Node();//调用Node的第一个构造方法 } public void insertHead(int val){ //头插法 Node n=new Node(val); n.next=this.head.next; head.next=n; } public boolean haveCircle(){//判断有环的思路为两个节点,fast走两步,slow走一步,若fast和slow最终相等,则证明有环,否则不会相等 if(head==null)return false; Node fast=head; Node slow=head; while(fast.next!=null && fast.next.next!=null){ fast=fast.next.next; slow=slow.next; if(fast==slow){ break; } } if(fast==slow)return true; else return false; } public Node firstCircleNode(){ //碰撞点到入口点的距离等于head到入口点的距离 if(!this.haveCircle())return null; Node fast=head.next.next; Node slow=head.next; while(fast!=slow){ fast=fast.next.next; slow=slow.next; } Node p=head; while(p!=slow){ p=p.next; slow=slow.next; } return p; } public int getCircleNodeNum(){//第一次相交与第二次相交slow所走过的节点个数; if(!this.haveCircle())return 0;//如果没有环则返回0; Node fast=head.next.next; Node slow=head.next; Node f1=null;Node f2=null; int count=0; while(f1==null || f2==null){ if(fast==slow && f1!=null){ f2=fast; } if(fast==slow && f1==null){ f1=fast; } if(f1!=null && f2==null){ count ++; } fast=fast.next.next; slow=slow.next; } return count; } private int listNode(LinkList list){//私有方法用来返回链表的节点数 int n=-1; Node p=list.head; while(p!=null){ p=p.next; n+=1; } return n; } private Node LinkCross(LinkList list){//分别求出两个链表的个数,让个数多的先走k(多的个数)步 Node p=this.head;//两链表相交,则从交点处汇聚为一条链 Node q=list.head; if(p==null || q==null)return null; int np=listNode(this); int nq=listNode(list); int n=np-nq; while(n>0){ p=p.next; n--; } while(n<0){ q=q.next; n++; } while(p!=null || q!=null){ if(p==q)break; p=p.next;q=q.next; } if(p==q)return p; else return null; } public boolean isLinkCross(LinkList list){//判断是否相交 Node p=LinkCross(list); if(p==null)return false; else return true; } public Node LinkNode(LinkList list){ return LinkCross(list); } public Node findReverseKNode(int k){//返回倒数第K个节点时间复杂度为O(n) int n=listNode(this); if(n<k)return null; Node f=head; Node s=head; while(k>0){ f=f.next; k--; } while(f!=null){ f=f.next; s=s.next; } return s; } public String toString(){ StringBuilder builder=new StringBuilder(); if(haveCircle())return "链表有环"; Node n=head; while(n.next!=null){ builder.append(n.next.value+" "); n=n.next; } return builder.toString(); } public LinkList createList(){ //随机生成单链表 LinkList L=new LinkList(); for(int i=0;i<10;i++){ L.insertHead((int)(Math.random()*10)); } return L; } public LinkList createCircleList(){ //随机生成带环链表 LinkList L=createList(); Random r=new Random(); int k=r.nextInt(10); //System.out.printf("环的入口节点为第%d个\n",k); Node p=L.head; Node q=L.head; while(p.next!=null){ if(k==0)q=p.next;//随机环的入口节点 k--; p=p.next; } p.next=q;//链接形成环; return L; } public void createLink(LinkList List){ Node p=head; while(p.next!=null){ p=p.next; } p.next=List.head.next; }}
3、在主函数中对各种方法进行调用检测
public class TLinkList { public static void main(String [] args) { LinkList L=new LinkList(); LinkList L1=L.createList(); LinkList L2=L.createCircleList(); System.out.println("判断L1链表是否有环:"+L1.haveCircle()); System.out.println("判断L2链表是否有环:"+L2.haveCircle()); System.out.println("有环链表的入口点的value值为:"+(L2.firstCircleNode()).value); System.out.println("计算环的节点个数:"+L2.getCircleNodeNum()); System.out.println("L1链表的倒数第3个节点为:"+L1.findReverseKNode(3).value); System.out.println("L1链表的节点元素为:"+L1.toString()); //创建两条相交链表L3、L4; LinkList L3=L.createList(); LinkList L4=L.createList(); L3.createLink(L1);//将L1链接在L3的末尾 L4.createLink(L1);//将L1链接在L4的末尾 System.out.println("判断L3和L4是否相交:"+L3.isLinkCross(L4)); System.out.println("两链表链接的节点元素的值为:"+L3.LinkNode(L4).value); System.out.println("L3链表的节点元素为:"+L3.toString()); System.out.println("L4链表的节点元素为:"+L4.toString()); }}
运行结果:
阅读全文
0 0
- java对链表(环、交叉链表的应用)
- Java实现-两个链表的交叉
- 两个链表的交叉
- 两个链表的交叉
- 两个链表的交叉
- 交叉工具链的简单应用
- 对循环链表的应用
- 链表是否交叉
- 链表交叉
- 链表交叉
- 交叉链表
- lintcode 交叉链表
- 制作交叉工具链时对文件etc_profile的更改
- 查找两个链表的交叉节点
- Lintcode 两个链表的交叉
- LintCode: 两个链表的交叉
- lintcode ----两个链表的交叉
- lintcode-两个链表的交叉
- JVM运行报错:GC overhead limit exceeded
- jQuery选择器与过滤器
- Python 清除线上数据oom内存溢出事件
- 1059. C语言竞赛(20)
- Sort the Array
- java对链表(环、交叉链表的应用)
- Android 获取listview中的文本 报错:android.widget.LinearLayout cannot be cast to android.widget.TextView
- linq insert The null value cannot be assigned to a member with type System.Int64 which is a non-null
- 出现GC overhead limit exceeded 的解决方案
- 1060. 爱丁顿数(25)
- 【数据库】实验一
- MySQL 存储过程中的游标使用
- 【软考】纠错1-3
- 结构体