Entrance algorithm with a single list to find the ring the ring (Java description language)

The story rings with a single list

@ Cheng pulls past do not understand the Reader, please read - "to determine whether there is a single chain ring algorithm"

How to Get inlet ring with ring single list

Here just say it more feasible algorithm.

An idea: HashSet first element is a repeat of the inlet ring

According to locate a single list with the idea of ​​ring Second, we have to maintain a HashSet ran elements, when repeated when that node is the entrance to the ring. This way to fairly so that, but still the old problem - space complexity large.

Thinking two: to open a pointer to meet with the current pointer

Our current two-pointer stopped at the intersection, there is a position.

I thought to want to still give you draw a map of it:
Here Insert Picture Description

There are two paintings wrong place: that is, in fact, L 1 should be drawn from the node4 to node7, then there are lines on the node6 should focus changed to node7.

It also reads the above article should also know that my test data is:
node1 → node2 → node3 → node4 → node5 → node6 → node7 → node8 → node9 → node4.
Node4 ring at the inlet.
We go according to the speed of the double pointer idea again determines ring processes:
T = 0: PREV = node1, REAR = node1;
T =. 1: PREV = node3, REAR = node2;
T = 2: PREV = Node5, REAR = node3;
. 3 = T: = Node7 PREV, REAR = Node4;
T =. 4: PREV = node9, REAR = Node5;
T =. 5: PREV = Node5, REAR = Node6;
T =. 6: PREV = Node7, REAR = Node7.
(Painting was wrong, in fact, should be met in node7 of ...... but do not affect the reasoning)

Obviously, the first round is bound to run slower pointer endless circle.

We did some definitions:
the initial point (node1) to loop entry point (Node4) is L 0 ;
(Node4) cycloalkyl entry point to the intersection (Node7) of L . 1 ;
intersection (Node7) to loop entry point (Node4) of L 2 ;
loop entry point (Node4) to (Node4) cycloalkyl entry point circle is R & lt;
slow pointer from passing the node is s, ran away pointer is fast and 2s in the ring (loop entry point (Node4 ) of cis to the ring entry point (Node4) circle within the ring) ran in n-turns.

Pointer finish due to the slow running lap, so that: (1) Since the n-run fast pointer circle, the extra portion of exactly L 1 , so that: (2) (2) - (1), to obtain: (3) Since the lap length is r, is L 1 + L 2 , so that: (4) from (4), we have: (5) (5) into the formula (1), we have: (6) and (6) obtained in (3), (7) (7) transposing obtained: (8) (8) is also desired.s = l0 + l1
2s = l0 + l1 + nr
s = nr
r = l1 + l2
l1 = r - l2
s = l0 + l1 = l0 + r - l2
s = nr = l0 + r - l2
l0 = (n-1)r + l2

(8) tell us?
A new discharge from node1 new pointer, a pointer to further drawn out from the rear prev and simultaneously new departure, each time a mobile node, an entry point will eventually ring (FIG Node4) meet at a meet moment, that point is the entrance to the ring.

This is a complete derivation of the algorithm. In fact, online, I do not understand how to push a lot of writing mess. I push myself a little, in conjunction with examples to explain to everyone here, but also look satisfied.

Java programming

First, before isCircular () is modified, the return boolean value is changed from Node, easy to call.

private Node<T> isCircular() {
    Node<T> prev = first;
    Node<T> rear = first;
    while (prev.next != null) {
        prev = prev.next;
        if (prev.next == null) {
            return null;
        }
        prev = prev.next;
        rear = rear.next;
        if (prev == rear) {
            return prev;
        }
    }
    return null;
}

Next is a new approach getEntry () a:

private Node<T> getEntry() {
    Node<T> prev = isCircular();
    if (prev == null) {
        return null;
    }
    Node<T> rear = first;
    while (prev != rear) {
        prev = prev.next;
        rear = rear.next;
    }
    return prev;
}

The complete code (Java description language)

public class Main {

    private static class Node<T> {
        T element;
        Node<T> next;
        Node(T element) {
            this.element = element;
        }
    }

    private static class LinkedList<T> {
        Node<T> first;
        private Node<T> isCircular() {
            Node<T> prev = first;
            Node<T> rear = first;
            while (prev.next != null) {
                prev = prev.next;
                if (prev.next == null) {
                    return null;
                }
                prev = prev.next;
                rear = rear.next;
                if (prev == rear) {
                    return prev;
                }
            }
            return null;
        }
        private Node<T> getEntry() {
            Node<T> prev = isCircular();
            if (prev == null) {
                return null;
            }
            Node<T> rear = first;
            while (prev != rear) {
                prev = prev.next;
                rear = rear.next;
            }
            return prev;
        }
    }

    public static void main(String[] args) {
        Node<Integer> node1 = new Node<>(1);
        Node<Integer> node2 = new Node<>(2);
        Node<Integer> node3 = new Node<>(3);
        Node<Integer> node4 = new Node<>(4);
        Node<Integer> node5 = new Node<>(5);
        Node<Integer> node6 = new Node<>(6);
        Node<Integer> node7 = new Node<>(7);
        Node<Integer> node8 = new Node<>(8);
        Node<Integer> node9 = new Node<>(9);
        node1.next = node2;
        node2.next = node3;
        node3.next = node4;
        node4.next = node5;
        node5.next = node6;
        node6.next = node7;
        node7.next = node8;
        node8.next = node9;
        node9.next = node4;
        LinkedList<Integer> list = new LinkedList<>();
        list.first = node1;
        System.out.println("链表是否有环:" + (list.isCircular() == null ? "false" : "true"));
        Node<Integer> entry = list.getEntry();
        System.out.println("链表环的入口是:" + (entry == null ? "不存在" : "Node"+entry.element));
    }

}
Published 538 original articles · won praise 1098 · Views 270,000 +

Guess you like

Origin blog.csdn.net/weixin_43896318/article/details/104384771