Ссылка на объект Java в другом объекте [дубликат]

Запомните это:

Потребители едят ужин (супер); Производитель продлевает фабрику своего родителя

387
задан Nicolas Barbulesco 5 May 2013 в 17:35
поделиться

24 ответа

Вы можете использовать алгоритм поиска циклов Флойда , также известный как алгоритм черепахи и зайца . Идея состоит в том, чтобы иметь две ссылки на список и перемещать их с разной скоростью. Переместите один вперед узлом 1, а другой - узлами 2.

  • Если связанный список имеет цикл, то он определенно встретится.
  • Еще одна из двух ссылок (или их next) будет [f6]

Функция Java, реализующая алгоритм:

boolean hasLoop(Node first) {

    if(first == null) // list does not exist..so no loop either
        return false;

    Node slow, fast; // create two references.

    slow = fast = first; // make both refer to the start of the list

    while(true) {

        slow = slow.next;          // 1 hop

        if(fast.next != null)
            fast = fast.next.next; // 2 hops
        else
            return false;          // next node null => no loop

        if(slow == null || fast == null) // if either hits null..no loop
            return false;

        if(slow == fast) // if the two ever meet...we must have a loop
            return true;
    }
}
490
ответ дан FrostRocket 17 August 2018 в 17:48
поделиться
  • 1
    Также необходимо выполнить нулевую проверку на fast.next, прежде чем снова вызвать next: if(fast.next!=null)fast=fast.next.next; – cmptrgeekken 18 April 2010 в 18:27
  • 2
    вы должны проверять не только (slow == fast), но: (slow == fast || slow.next == fast), чтобы предотвратить прыжок быстрее медленного – Oleg Razgulyaev 18 April 2010 в 18:55
  • 3
    я был не прав: быстро не могу перепрыгнуть через медленный, потому что прыгать через медленный на следующем шаге быстро должен иметь то же самое место, что и медленное :) – Oleg Razgulyaev 19 April 2010 в 08:21
  • 4
    Проверка на медленный == null избыточна, если только в списке нет только одного узла. Вы также можете избавиться от одного вызова Node.next. Вот более простая и быстрая версия цикла: pastie.org/927591 – Kay Sarraute 21 April 2010 в 12:32
  • 5
    Вы действительно должны ссылаться на свои рекомендации. Этот алгоритм был изобретен Робертом Флойдом в 60-х годах, он известен как алгоритм поиска циклов Флойда, ака. Алгоритм черепахи и зайца. – joshperry 18 May 2010 в 17:30

Возможно, я очень устал и новичок в этой теме. Но все же ..

Почему не может быть указан адрес узла, а указатель «следующий» указывается в таблице

. Если мы могли бы табулировать этот путь

node present: (present node addr) (next node address)

node 1: addr1: 0x100 addr2: 0x200 ( no present node address till this point had 0x200)
node 2: addr2: 0x200 addr3: 0x300 ( no present node address till this point had 0x300)
node 3: addr3: 0x300 addr4: 0x400 ( no present node address till this point had 0x400)
node 4: addr4: 0x400 addr5: 0x500 ( no present node address till this point had 0x500)
node 5: addr5: 0x500 addr6: 0x600 ( no present node address till this point had 0x600)
node 6: addr6: 0x600 addr4: 0x400 ( ONE present node address till this point had 0x400)

Следовательно, образуется цикл.

0
ответ дан Adit Ya 17 August 2018 в 17:48
поделиться
  • 1
    Ваше решение не передает «постоянное количество пространства». требование. – Arnaud 7 October 2015 в 12:37
boolean hasCycle(Node head) {

    boolean dec = false;
    Node first = head;
    Node sec = head;
    while(first != null && sec != null)
    {
        first = first.next;
        sec = sec.next.next;
        if(first == sec )
        {
            dec = true;
            break;
        }

    }
        return dec;
}

Используйте функцию выше, чтобы обнаружить цикл в связанном списке в java.

0
ответ дан Aditya Parmar 17 August 2018 в 17:48
поделиться
  • 1
    Почти так же, как и мой ответ выше, но есть проблема. Он будет генерировать исключение NullPointerException для списков с списками нечетной длины (без циклов). Например, если head.next имеет значение NULL, тогда sec.next.next выдает NPE. – Dave L. 13 September 2017 в 16:49

Лучше, чем алгоритм Флойда

Ричард Брент описал алгоритм обнаружения альтернативного цикла , который в значительной степени похож на зайца и черепаху [цикл Флойда ], за исключением того, что медленный узел здесь не перемещается, а затем «телепортируется» в положение быстрого узла с фиксированными интервалами.

Описание доступно здесь: http://www.siafoo.net/algorithm/11 Брент утверждает, что его алгоритм на 24-36% быстрее, чем алгоритм цикла Флойда. O (n), сложность пространства O (1).

public static boolean hasLoop(Node root){
    if(root == null) return false;

    Node slow = root, fast = root;
    int taken = 0, limit = 2;

    while (fast.next != null) {
        fast = fast.next;
        taken++;
        if(slow == fast) return true;

        if(taken == limit){
            taken = 0;
            limit <<= 1;    // equivalent to limit *= 2;
            slow = fast;    // teleporting the turtle (to the hare's position) 
        }
    }
    return false;
}
45
ответ дан Ashok Bijoy Debnath 17 August 2018 в 17:48
поделиться
  • 1
    Этот ответ потрясающий! – valin077 10 June 2014 в 20:00
  • 2
    Очень понравился ваш ответ, включил его в мой блог - k2code.blogspot.in/2010/04/… . – kinshuk4 16 October 2014 в 19:48
  • 3
    Зачем вам нужно проверять slow.next != null? Насколько я вижу, slow всегда позади или равен fast. – TWiStErRob 19 November 2015 в 10:38
  • 4
    Я сделал это давным-давно, когда начал изучать алгоритмы. Отредактировал код. Благодаря :) – Ashok Bijoy Debnath 19 November 2015 в 11:53

Пользователь unicornaddict имеет хороший алгоритм выше, но, к сожалению, он содержит ошибку для нециклических списков нечетной длины> = 3. Проблема в том, что fast может «застрять» просто до конца списка, slow догоняет его, и обнаружен цикл (ошибочно).

Вот исправленный алгоритм.

static boolean hasLoop(Node first) {

    if(first == null) // list does not exist..so no loop either.
        return false;

    Node slow, fast; // create two references.

    slow = fast = first; // make both refer to the start of the list.

    while(true) {
        slow = slow.next;          // 1 hop.
        if(fast.next == null)
            fast = null;
        else
            fast = fast.next.next; // 2 hops.

        if(fast == null) // if fast hits null..no loop.
            return false;

        if(slow == fast) // if the two ever meet...we must have a loop.
            return true;
    }
}
13
ответ дан Community 17 August 2018 в 17:48
поделиться

Вот уточнение решения Fast / Slow, которое правильно обрабатывает списки нечетных длин и улучшает четкость.

boolean hasLoop(Node first) {
    Node slow = first;
    Node fast = first;

    while(fast != null && fast.next != null) {
        slow = slow.next;          // 1 hop
        fast = fast.next.next;     // 2 hops 

        if(slow == fast)  // fast caught up to slow, so there is a loop
            return true;
    }
    return false;  // fast reached null, so the list terminates
}
99
ответ дан Dave L. 17 August 2018 в 17:48
поделиться
  • 1
    Хороший и лаконичный. Этот код можно оптимизировать, проверяя, если slow == fast || (fast.next! = null & amp; & amp; slow = fast.next); :) – arachnode.net 26 February 2013 в 05:16
  • 2
    @ arachnode.net Это не оптимизация. Если slow == fast.next, то slow будет равно fast на самой следующей итерации; он экономит только одну итерацию максимум за счет дополнительного теста для каждой итерации. – Jason C 6 March 2014 в 01:59
  • 3
    @ ana01 slow не может стать нулевым до fast, поскольку он соответствует одному и тому же пути ссылок (если у вас нет одновременной модификации списка, в этом случае все ставки отключены). – Dave L. 15 October 2014 в 15:57
  • 4
    Из любопытства, как это работает на нечетные числа? Не может ли зайца по-прежнему проходить черепаху на нечетных связанных страницах? – theGreenCabbage 20 September 2015 в 05:03
  • 5
    @ theGreenCabbage Каждая итерация петли зайца на 1 шаг вперед впереди черепахи. Так что если заяц отстает на 3 шага, то следующая итерация занимает два прыжка, а черепаха занимает один прыжок, а теперь заяц отстает на 2 шага. После следующей итерации заяц отстает на 1 прыжок, а затем он точно догоняет. Если заяц взял 3 прыжка, в то время как черепаха взял один, то он мог пропустить, потому что он получал бы по 2 раза каждый раз, но поскольку он выигрывает только на 1 итерации, он не может пропустить мимо. – Dave L. 20 September 2015 в 23:51
public boolean isCircular() {

    if (head == null)
        return false;

    Node temp1 = head;
    Node temp2 = head;

    try {
        while (temp2.next != null) {

            temp2 = temp2.next.next.next;
            temp1 = temp1.next;

            if (temp1 == temp2 || temp1 == temp2.next) 
                return true;    

        }
    } catch (NullPointerException ex) {
        return false;

    }

    return false;

}
-2
ответ дан edst 17 August 2018 в 17:48
поделиться

Вы могли бы даже сделать это в постоянное время O (1) (хотя это было бы не очень быстро или эффективно): существует ограниченное количество узлов, хранящихся в памяти вашего компьютера, например N записей. Если вы пересекаете более N записей, тогда у вас есть цикл.

1
ответ дан Eduardo 17 August 2018 в 17:48
поделиться

Вот мой исполняемый код.

Я сделал это, чтобы почитать связанный список, используя три временных узла (сложность пространства O(1)), которые отслеживают ссылки.

Интересный факт заключается в том, чтобы помочь обнаружить цикл в связанном списке, потому что, когда вы продвигаетесь вперед, вы не ожидаете вернуться к начальной точке (корневому узлу) и одному из временных узлы должны идти до нуля, если у вас нет цикла, что означает, что он указывает на корневой узел.

Временная сложность этого алгоритма - O(n), а сложность пространства - O(1).

Вот узел класса для связанного списка:

public class LinkedNode{
    public LinkedNode next;
}

Вот основной код с простым тестовым случаем из трех узлов, который последний узел указывает на второй узел:

    public static boolean checkLoopInLinkedList(LinkedNode root){

        if (root == null || root.next == null) return false;

        LinkedNode current1 = root, current2 = root.next, current3 = root.next.next;
        root.next = null;
        current2.next = current1;

        while(current3 != null){
            if(current3 == root) return true;

            current1 = current2;
            current2 = current3;
            current3 = current3.next;

            current2.next = current1;
        }
        return false;
    }

Вот простой тестовый пример из трех узлов, который указывает последний узел ко второму узлу:

public class questions{
    public static void main(String [] args){

        LinkedNode n1 = new LinkedNode();
        LinkedNode n2 = new LinkedNode();
        LinkedNode n3 = new LinkedNode();
        n1.next = n2;
        n2.next = n3;
        n3.next = n2;

        System.out.print(checkLoopInLinkedList(n1));
    }
}
0
ответ дан Habib Karbasian 17 August 2018 в 17:48
поделиться

Вот мое решение в java

boolean detectLoop(Node head){
    Node fastRunner = head;
    Node slowRunner = head;
    while(fastRunner != null && slowRunner !=null && fastRunner.next != null){
        fastRunner = fastRunner.next.next;
        slowRunner = slowRunner.next;
        if(fastRunner == slowRunner){
            return true;
        }
    }
    return false;
}
-1
ответ дан Irshad ck 17 August 2018 в 17:48
поделиться

Обнаружение цикла в связанном списке может быть выполнено одним из самых простых способов, что приводит к сложности O (N).

По мере прохождения списка, начиная с главы, создайте отсортированный список адреса. Когда вы вставляете новый адрес, проверьте, есть ли адрес в отсортированном списке, который выполняет сложность O (logN).

0
ответ дан J.S. 17 August 2018 в 17:48
поделиться

Алгоритм

public static boolean hasCycle (LinkedList<Node> list)
{
    HashSet<Node> visited = new HashSet<Node>();

    for (Node n : list)
    {
        visited.add(n);

        if (visited.contains(n.next))
        {
            return true;
        }
    }

    return false;
}

Сложность

Time ~ O(n)
Space ~ O(n)
8
ответ дан Khaled.K 17 August 2018 в 17:48
поделиться
  • 1
    Как пространственная сложность O (2n)? – Programmer345 13 April 2015 в 13:36
  • 2
    @ user3543449 вы правы, это должно быть просто n, исправлено – Khaled.K 20 April 2015 в 07:07
  • 3
    Это фактически время ~ O (n ^ 2), так как каждый содержит проверку для ArrayList, принимает O (n) и их O (n). Вместо этого используйте HashSet для линейного времени. – Dave L. 17 June 2015 в 16:08
  • 4
    Это не проверяет циклы, а дублирует значения с помощью элементов equals и hashCode. Это не одно и то же. И это разметки null на последнем элементе. И вопрос ничего не сказал о хранении узлов в LinkedList. – Lii 17 August 2015 в 18:35
  • 5
    @Lii это псевдокод, это не код Java, поэтому я назвал его с помощью Algorithm – Khaled.K 25 February 2016 в 10:59

Альтернативное решение для Черепахи и Кролика, не совсем так приятно, поскольку я временно меняю список:

Идея состоит в том, чтобы ходить по списку и отменить его, когда вы идете. Затем, когда вы впервые достигнете узла, который уже был посещен, его следующий указатель будет указывать «назад», в результате чего итерация снова начнется к first, где она завершается.

Node prev = null;
Node cur = first;
while (cur != null) {
    Node next = cur.next;
    cur.next = prev;
    prev = cur;
    cur = next;
}
boolean hasCycle = prev == first && first != null && first.next != null;

// reconstruct the list
cur = prev;
prev = null;
while (cur != null) {
    Node next = cur.next;
    cur.next = prev;
    prev = cur;
    cur = next;
}

return hasCycle;

Тестовый код :

static void assertSameOrder(Node[] nodes) {
    for (int i = 0; i < nodes.length - 1; i++) {
        assert nodes[i].next == nodes[i + 1];
    }
}

public static void main(String[] args) {
    Node[] nodes = new Node[100];
    for (int i = 0; i < nodes.length; i++) {
        nodes[i] = new Node();
    }
    for (int i = 0; i < nodes.length - 1; i++) {
        nodes[i].next = nodes[i + 1];
    }
    Node first = nodes[0];
    Node max = nodes[nodes.length - 1];

    max.next = null;
    assert !hasCycle(first);
    assertSameOrder(nodes);
    max.next = first;
    assert hasCycle(first);
    assertSameOrder(nodes);
    max.next = max;
    assert hasCycle(first);
    assertSameOrder(nodes);
    max.next = nodes[50];
    assert hasCycle(first);
    assertSameOrder(nodes);
}
47
ответ дан meriton 17 August 2018 в 17:48
поделиться
  • 1
    +1 быстрее, чем черепаха и кролик – Peter G. 21 July 2010 в 18:01
  • 2
    Правильно ли работает реконструкция? & Lt; br / & gt; – Zenil 8 March 2015 в 02:01
  • 3
    Правильно ли работает обратное, когда цикл указывает на любой узел, отличный от первого? Если исходный связанный список подобен этому 1- & gt; 2- & gt; 4 & gt; 5 & gt; 2 (с циклом от 5 до 2), тогда перевернутый список выглядит как 1- & gt; 2 & lt; ; -3 & lt; -4 & lt; -5 & le; И если наоборот, окончательный реконструированный список будет прикручен? – Zenil 8 March 2015 в 02:08
  • 4
    @Zenil: Вот почему я написал этот последний тестовый файл, где последний узел указывает на середину списка. Если реконструкция не будет работать, это испытание потерпит неудачу. Пример вашего примера: разворот 1- & gt; 2- & gt; 5 & gt; 5 & gt; 2 будет 1 & gt; 2- & gt; 5- & gt; 3 & gt; 3 & gt; 2, цикл останавливается только после того, как достигнут конец списка, а не когда конец цикла (который мы не можем легко обнаружить). – meriton 8 March 2015 в 02:58

Черепаха и заяц

Взгляните на алгоритм Роллара Полларда . Это не совсем та же проблема, но, может быть, вы поймете ее логику и примените ее к связанным спискам.

(если вы ленивы, вы можете просто проверить обнаружение цикла - проверьте часть черепахи и зайца.)

Для этого требуется только линейное время и 2 дополнительных указателя.

В Java:

boolean hasLoop( Node first ) {
    if ( first == null ) return false;

    Node turtle = first;
    Node hare = first;

    while ( hare.next != null && hare.next.next != null ) {
         turtle = turtle.next;
         hare = hare.next.next;

         if ( turtle == hare ) return true;
    }

    return false;
}

(Большинство решений не проверяют как для next, так и для next.next для нулей. Кроме того, поскольку черепаха всегда отстает, вам не нужно проверять ее на нуль - заяц сделал это уже. )

28
ответ дан Mikesname 17 August 2018 в 17:48
поделиться

Этот подход имеет пространственные накладные расходы, но более простая реализация:

Петля может быть идентифицирована путем хранения узлов на карте. И прежде чем положить узел; проверьте, существует ли узел. Если узел уже существует на карте, это означает, что Linked List имеет цикл.

public boolean loopDetector(Node<E> first) {  
       Node<E> t = first;  
       Map<Node<E>, Node<E>> map = new IdentityHashMap<Node<E>, Node<E>>();  
       while (t != null) {  
            if (map.containsKey(t)) {  
                 System.out.println(" duplicate Node is --" + t  
                           + " having value :" + t.data);  

                 return true;  
            } else {  
                 map.put(t, t);  
            }  
            t = t.next;  
       }  
       return false;  
  }  
-1
ответ дан rai.skumar 17 August 2018 в 17:48
поделиться
  • 1
    Это не соответствует ограничению ограничения пространства , заданного в вопросе! – dedek 26 June 2014 в 12:36
  • 2
    согласитесь, что у него есть накладные расходы; это еще один подход к решению этой проблемы. Очевидным подходом является алгоритм черепахи и гарсы. – rai.skumar 26 June 2014 в 12:50
  • 3
    @downvoter, было бы полезно, если бы вы могли объяснить причину. – rai.skumar 7 August 2017 в 05:20
 // To detect whether a circular loop exists in a linked list
public boolean findCircularLoop() {
    Node slower, faster;
    slower = head;
    faster = head.next; // start faster one node ahead
    while (true) {

        // if the faster pointer encounters a NULL element
        if (faster == null || faster.next == null)
            return false;
        // if faster pointer ever equals slower or faster's next
        // pointer is ever equal to slower then it's a circular list
        else if (slower == faster || slower == faster.next)
            return true;
        else {
            // advance the pointers
            slower = slower.next;
            faster = faster.next.next;
        }
    }
}
1
ответ дан Richa 17 August 2018 в 17:48
поделиться

Этот код оптимизирован и приведет к результату быстрее, чем к выбранному в качестве наилучшего ответа. Этот код экономит от перехода на очень длительный процесс преследования указателя на передний и задний узлы, который будет происходить в следующем случае, если мы последуем метод «лучшего ответа». Посмотрите на сухой пробег следующего, и вы поймете, что я пытаюсь сказать. Затем посмотрите на проблему с помощью приведенного ниже метода и измерьте «нет». шагов, предпринятых для поиска ответа.

1-> 2-> 9-> 3 ^ -------- ^

Вот код:

boolean loop(node *head)
{
 node *back=head;
 node *front=head;

 while(front && front->next)
 {
  front=front->next->next;
  if(back==front)
  return true;
  else
  back=back->next;
 }
return false
}
0
ответ дан Sarthak Mehra 17 August 2018 в 17:48
поделиться
  • 1
    Вы уверены, что это дает правильный результат во всех ситуациях? Если вы запустите этот алгоритм в списке 1 - & gt; 2 - & gt; 3 - & gt; 4 - & gt; 5 - & gt; 6 - & gt; 7 - & gt; 3 - & gt; ..., я считаю, что он вернет 4 в качестве головы, тогда как вам нужно 3. – Sunreef 27 June 2016 в 20:38
  • 2
    Вопрос заключается в том, чтобы найти, существует ли цикл или нет. В этом случае да, вопрос будет полностью работать нормально и получить желаемый логический результат для case.If вам нужен точный узел, с которого был запущен цикл, тогда мы будем нужно добавить что-то большее к коду. Но что касается создания результата, это приведет к более быстрому выводу. – Sarthak Mehra 28 June 2016 в 13:08
  • 3
    Вы не правильно прочитали вопрос: как лучше всего написать boolean hasLoop(Node first), который вернет true, если данный узел является первым из списка с циклом, а false в противном случае? – Sunreef 28 June 2016 в 13:10
  • 4
    Ниже приведен сухой пробег для вашего списка. Первое значение означает обратный указатель, а вторая часть означает указатель вперед (1,1) - (1,3) - (2,3) - (2,5) - (3,5) - (3,7) - (4,7) - (4,4). – Sarthak Mehra 28 June 2016 в 13:12
  • 5
    Ладно, извини, что я ошибся. – Sarthak Mehra 28 June 2016 в 13:16

Если нам разрешено вставлять класс Node, я бы решил проблему, как я ее реализовал ниже. hasLoop() работает в O (n) времени и занимает только пространство counter. Кажется ли это подходящим решением? Или есть способ сделать это без вложения Node? (Очевидно, что в реальной реализации было бы больше методов, таких как RemoveNode(Node n) и т. Д.)

public class LinkedNodeList {
    Node first;
    Int count;

    LinkedNodeList(){
        first = null;
        count = 0;
    }

    LinkedNodeList(Node n){
        if (n.next != null){
            throw new error("must start with single node!");
        } else {
            first = n;
            count = 1;
        }
    }

    public void addNode(Node n){
        Node lookingAt = first;

        while(lookingAt.next != null){
            lookingAt = lookingAt.next;
        }

        lookingAt.next = n;
        count++;
    }

    public boolean hasLoop(){

        int counter = 0;
        Node lookingAt = first;

        while(lookingAt.next != null){
            counter++;
            if (count < counter){
                return false;
            } else {
               lookingAt = lookingAt.next;
            }
        }

        return true;

    }



    private class Node{
        Node next;
        ....
    }

}
3
ответ дан smessing 17 August 2018 в 17:48
поделиться
  • 1
    Да, решение с каким-то набором работает отлично, но требует пространства, пропорционального размеру списка. – jjujuma 21 April 2010 в 12:51

Следующим может быть не лучший метод - это O (n ^ 2). Тем не менее, это должно служить для выполнения работы (в конечном итоге).

count_of_elements_so_far = 0;
for (each element in linked list)
{
    search for current element in first <count_of_elements_so_far>
    if found, then you have a loop
    else,count_of_elements_so_far++;
}
8
ответ дан Sparky 17 August 2018 в 17:48
поделиться
  • 1
    Как вы знаете, сколько элементов в списке выполняет for ()? – Jethro Larson 21 May 2015 в 00:17
  • 2
    @JethroLarson: последний узел в связанном списке указывает на известный адрес (во многих реализациях это NULL). Завершите цикл for, когда этот известный адрес будет достигнут. – Sparky 21 May 2015 в 19:48

Я не вижу никакого способа сделать это фиксированным количеством времени или пространства, оба будут увеличиваться с размером списка.

Я бы использовал IdentityHashMap (учитывая, что нет но IdentityHashSet) и хранить каждый узел в карте. Прежде чем узел будет сохранен, вы вызовете containsKey на нем. Если узел уже существует, у вас есть цикл.

ItentityHashMap использует == вместо .equals, чтобы вы проверяли, где находится объект в памяти, а не в том же содержимом.

0
ответ дан TofuBeer 17 August 2018 в 17:48
поделиться
  • 1
    Это, конечно, невозможно для фиксированного количества времени, так как в самом конце списка может быть цикл, поэтому весь список должен быть посещен. Однако алгоритм Fast / Slow демонстрирует решение с использованием фиксированного объема памяти. – Dave L. 21 July 2010 в 17:32
  • 2
    Разве это не относится к его асимптотическому поведению, т. Е. Оно является линейным O (n), где n - длина списка. Исправлено: O (1) – Mark Robson 15 September 2015 в 21:26

Вот решение для определения цикла.

public boolean hasCycle(ListNode head) {
            ListNode slow =head;
            ListNode fast =head;

            while(fast!=null && fast.next!=null){
                slow = slow.next; // slow pointer only one hop
                fast = fast.next.next; // fast pointer two hops 

                if(slow == fast)    return true; // retrun true if fast meet slow pointer
            }

            return false; // return false if fast pointer stop at end 
        }
0
ответ дан vishwaraj 17 August 2018 в 17:48
поделиться

Вы можете использовать алгоритм черепахи Флойда, как это предложено в вышеприведенных ответах.

Этот алгоритм может проверить, имеет ли одиночный список замкнутый цикл. Это может быть достигнуто путем итерации списка двумя указателями, которые будут двигаться с разной скоростью. Таким образом, если есть цикл, два указателя будут встречаться в какой-то момент в будущем.

Пожалуйста, не стесняйтесь проверить мой блог в блоге в структуре данных связанных списков , где я также включил фрагмент кода с реализацией вышеупомянутого алгоритма в Java-языке.

С уважением,

Andreas (@xnorcode)

0
ответ дан xnorcode 17 August 2018 в 17:48
поделиться
3
ответ дан smessing 6 September 2018 в 11:33
поделиться
3
ответ дан smessing 29 October 2018 в 18:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: