单链表的一些问题

1.单链表的逆置

    public Entry reverse(){
        Entry newHead = null;
        Entry prev = null;
        Entry cur = head;
        while(cur != null){
            Entry curNext = cur.next;
            if(curNext == null){
                newHead = cur;
            }
            cur.next = prev;
            prev = cur;
            cur = curNext;
        }
        return newHead;
    }

这里写图片描述
求倒数第k个元素

    public int lastK(int k){
        if(k<0||k>getLength()){
            return -1;
        }   
        Entry cur1 = head;
        Entry cur2 = head;
        while(k-1>0){
            if(cur2.next != null){//让cur先走k-1步
                cur2 = cur2.next ;
                --k;
            }else{
                return -1;
            }
        }
        while(cur2.next !=null){//cur1,cur2一起往前走
            cur1 = cur1.next;
            cur2 = cur2.next;
        }
        if(cur2.next ==null ){
            return cur1.data ;
        }else{
            return -1;
        }
    }

当k=2时:
这里写图片描述
判断单链表是否有环(一快一慢能相遇就有环)

    public boolean isLoop(){
        Entry fast = head;
        Entry slow = head;
        while(fast != null && fast.next != null){
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow){
                return true;
            }
        }
        return false;
    }

这里写图片描述
环的入口点

    public int getEntryLoop(){
        if(!isLoop()){
            return -1;
        }
        Entry fast = head;
        Entry slow = head;
        while(fast != null && fast.next != null){
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow){//记录相遇点
                break;
            }
        }
        slow = head;//slow回到head
        while(fast != slow){//当slow与fast一人一步走相同长度再次相遇时,就是环的起始点
            fast = fast.next;
            slow = slow.next;
        }
        return slow.data;
    }

这里写图片描述
相遇时fast走过的路程:n+y
相遇时slow走过的路程:x+y
环的长度:n-x
fast速度是slow速度的2倍,即2(x+y)=n+y,可得x=n-x-y,而n-x为环的长度,y为从环的起始点到相遇点的长度,那么n-x-y就是从相遇点再次回到起始点的长度,这个长度恰好等于从head到环的起始点的长度。
环的长度

    public int getLengthLoop(){
        int len = 0;
        Entry fast = head;
        Entry slow = head;
        boolean tag = false;
        while(fast != null && fast.next != null){
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow && tag == true){//第二次相遇
                break;
            }
            if(fast == slow && tag == false){//第一次相遇
                tag = true;
            }
            if(tag = true){//第一次相遇后开始计数直到第二次相遇
                len++;
            }
        }
        return len;
    }

链表相交

    public boolean isCut(TestLink t1,TestLink t2){
        TestLink.Entry head1 = t1.getHead();
        TestLink.Entry head2 = t2.getHead();

        int len1 = t1.getLength();
        int len2 = t2.getLength();
        int my_len = len1-len2;
        if(my_len<0){//使head1指向的单链表是最长的
            head1 = t2.getHead();
            head2 = t1.getHead();
            my_len = -(my_len);//my_len始终为正数
        }
        for(int i =0;i<my_len;i++){//head1先走my_len步,使head1与head2距交点距离一样
            head1 = head1.next;
        }
        while(head1 != null && head2 != null && head1 != head2){
            //一人一步走
            head1 = head1.next;
            head2 = head2.next;
        }
        if(head1 == head2 && head1 != null && head2 != null){//相遇
            return true;
        }else{
            return false;
        }
    }

猜你喜欢

转载自blog.csdn.net/mars1997/article/details/80107368