数据结构—链表(三)

来源:互联网 发布:淘宝手机版店招制作 编辑:程序博客网 时间: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
原创粉丝点击