【问题标题】:how to find number of nodes in loop of linked list?如何查找链表循环中的节点数?
【发布时间】:2010-10-12 10:22:37
【问题描述】:

如何查找链表循环中的节点数?

例如

A ----> B ----> C -----> D -----> E
                Λ                 |
                |                 |
                |                 V
                H <----- G <----- F 

查找从 C 到 H 的循环中的节点数

基本问题是如何找到C点。我们可以使用传统的兔子和乌龟算法,但它并不是每次都在C点相遇。

【问题讨论】:

  • 如果您只需要循环的大小而不需要从 A 到 C 的距离,它们是否在 C 中相遇并不重要。

标签: algorithm linked-list


【解决方案1】:

有关如何在链表中查找循环的更多解决方案,请参阅here。添加节点计数非常简单。 (虽然龟兔赛跑可能是最好的)

【讨论】:

    【解决方案2】:

    如果你只是想找到答案,那就用龟兔赛跑来确定什么时候肯定有一个循环。然后启动一个计数器,计算你必须进行多少次迭代才能到达你第一次找到的点。这可能不是最有效的,但它给出了正确的答案。

    一些 C++ 代码:

    #include <iostream>
    
    struct node
    {
      node(node* next)
        : next(next)
      { }
    
      node* next;
    };
    
    int main(int argc, char* argv[])
    {
      node h(NULL), g(&h), f(&g), e(&f), d(&e), c(&d), b(&c), a(&b);
      h.next = &c;
    
      node* tortoise = &a;
      node* hare = &b;
    
      while(tortoise != hare)
      {
        tortoise = tortoise->next;
        hare = hare->next->next;
      }
    
      int count = 1;
      tortoise = tortoise->next;
    
      while(tortoise != hare)
      {
        ++count;
        tortoise = tortoise->next;
      }
    
      std::cout << "Size of cycle: " << count << "\n";
    
      return 0;
    }
    

    请注意,如果您实际上没有循环,则必须做一些额外的工作来确定您是否到达终点,而不是循环。传统的龟兔应该注意这一点:

    http://en.wikipedia.org/wiki/Cycle_detection

    【讨论】:

      【解决方案3】:
      List visited;
      List toVisit;
      
      toVisit.add(A);                         // add the first Node
      while(toVisit is not empty){
        Node current = visited.remove();
        Array <Node> links = current.getLinks();
        for(int i=0; i<links.size(); i++){
          if(!visited.contains(links[i])){    // if the link has NOT already been visited add it to the toVisit List
            toVisit.add(links[i]);
          }        
        visited.add(current);                 // mark current as visited
        }
      }
      return visited.size();                  // to get the number of nodes in the graph
      

      【讨论】:

        【解决方案4】:

        我不认为我会认为这是一个linkedList。 LinkedLists 通常以空指针或指向结束符号的指针结束。即:start -&gt; A -&gt; B -&gt; C -&gt; end。我认为这将是一种特定的图表。

        要找到图中的节点总数,我会这样做:

        List visited;
        List toVisit;
        
        toVisit.add(A);                         // add the first Node
        while(toVisit is not empty){
          Node current = visited.remove();
          Array <Node> links = current.getLinks();
          for(int i=0; i<links.size(); i++){
            if(!visited.contains(links[i])){    // if the link has NOT already been visited add it to the toVisit List
              toVisit.add(links[i]);
            }        
          visited.add(current);                 // mark current as visited
          }
        }
        return visited.size();                  // to get the number of nodes in the graph
        

        如果你总是知道会有一个循环,比如(注意...):

        A ---> ... ---> C -----> D -----> E
                        Λ                 |
                        |                 |
                        |                 V
                        ... <----- G <--- F 
        

        你可以这样修改代码:

        List visited;
        
        Node current = firstNode;
        while(!visited.contains(firstNode)){
          Node next = current.getNext();      
          visited.add(current);                       // mark current as visited
          current=next;
        }
        // our ending condition is when we have found the same node again.  
        int currentIndex = visited.indexOf(current);
        int size = visited.size();
        int sizeOfLoop = size - currentIndex;
        return sizeOfLoop;
        

        【讨论】:

          【解决方案5】:

          1) flyod alogo 找到循环 2) 当 slow_ptr=fast_ptr 时,求循环中的节点数(k)

          此外,您还可以像这样转到 C:- 3) 开始 2 ptr ,一个从 head 开始,另一个从 head+k 开始。 4) 你们会在 Loop (C) 开始时见面

          【讨论】:

            猜你喜欢
            • 2011-02-25
            • 2013-08-27
            • 1970-01-01
            • 2015-08-08
            • 2012-07-20
            • 1970-01-01
            • 2012-06-08
            • 2019-01-30
            相关资源
            最近更新 更多