在单链表中查找周期

时间:2013-12-26 02:18:49

标签: c++ linked-list cycle

在单链表中查找循环并找到循环开始的节点。 我已经看到使用两个指针(通常是慢速和快速)来查找循环,但我已经编写了这个代码,它似乎工作正常。我的问题是,是否存在我的代码遗漏的问题,同时在单链表中查找循环。

Node* find_cycle_node(Node *head){
Node *p=head;
     Node *q;
     while(p->next!=null)
    { 
              q=p->next;
        while(q->next!=null)
          { 
                     if(p==q) return q; //Node repeated i.e cycle
                     else (q=q->next;)
           }
                p=p->next;
      }
    return null; // no cycle detected
}

6 个答案:

答案 0 :(得分:5)

如果有一个循环是句柄下面的几个节点,你的内部循环将不会终止,例如,它将是一个无限循环,如下所示:

1 -> 2 -> 3 -> 4 -> 5
          ^         |
          |         |
          +---------+

答案 1 :(得分:1)

这个怎么样?

struct Node_
{
    int ix ;
    struct Node_* next ;
} ;
typedef struct Node_ NODE ;
NODE *head = NULL ;

int main()
{
    NODE* n1 ;
    n1 = (NODE*) malloc(sizeof(NODE)) ;
    n1->ix = 0 ;
    n1->next = NULL ;
    head = n1 ;
    NODE* n2 ;
    n2 = (NODE*) malloc(sizeof(NODE)) ;
    n2->ix = 1 ;
    n2->next = NULL ;
    n1->next = n2 ;
    NODE* n3 ;
    n3 = (NODE*) malloc(sizeof(NODE)) ;
    n3->ix = 2 ;
    n3->next = NULL ;
    n2->next = n3 ;
    NODE* n4 ;
    n4 = (NODE*) malloc(sizeof(NODE)) ;
    n4->ix = 3 ;
    n4->next = n2 ;
    n3->next = n4 ;

    unordered_map<NODE*,int> hashx ;
    int idx ;
    NODE* p = head ;
    while(p != NULL)
    {
        hashx[p] += 1 ;
        if(hashx[p] >= 2)
        {
            printf("node p (%d) recycle !!\n",p->ix);
            break ;
        }
        p = p->next ;
    }
    printf("done \n") ;
} //main

答案 2 :(得分:0)

  

我的代码遗漏了

return; // no cycle detected

这条线看起来很糟糕,应该改为s.th.像

return NULL; // no cycle detected

答案 3 :(得分:0)

对我而言,你的内循环条件似乎含糊不清。您正在分析if(p == q)其中q是p->下一个。这意味着先前考虑的节点p没有进行循环。所以对我来说,你的内循环永远不会终止。

你必须考虑这个: -

#include <iostream>
using namespace std;
class Node{
    public:
        int data;
        Node * next;
        Node(int x){
            data = x;
            next = NULL;
        }
        Node(int x, Node * y){
            data = x; 
            next = y;
        }
};
class linkedList{
    Node *head;
    public:
        linkedList(){
            head = NULL;
        }
        void addNode(int value){
            Node *p;
            if(head == NULL)
                head = new Node (value, NULL);
            else{
                p = head;
                while(p->next !=NULL)
                    p=p->next;
                    p->next = new Node (value, NULL);
            }
        }
        void print(){
            Node * p;
            p = head;
            while(p != NULL){
                cout << p->data;
                p = p->next;
            }
        }
        int findCycle(){
            Node *p, *start, *q;
            p = head;
            while(p != NULL){
                q = p->next;
                while (q != NULL ){
                    if(p->data == q->data)
                         return q->data;
                    else
                         q = q->next;
                }
                p = p->next;
            }
            return 0;
        }
};
int main(){
    linkedList l1;
    l1.addNode(1);
    l1.addNode(2);
    l1.addNode(3);
    l1.addNode(4);
    l1.addNode(5);
    l1.addNode(3);
    int node = l1.findCycle();
    cout<<node;
    return 0;
}

你对这段代码说了什么。

答案 4 :(得分:0)

x=1+${emptyVar:-0}

{     //构建一个包含循环的列表

void LinkListOps::createCycledListAndFindACycleNode()

}

答案 5 :(得分:0)

您可以通过执行以下操作快速查明链接列表中是否存在循环:

ptr = head;
current = nullptr;
if (!ptr) {
  current = ptr->next;
  while(current && current!=ptr) {
    current = current->next;
    if (current) {
      current = current->next;
    }
    ptr = ptr->next;
  }
}

在此结束时,如果current不为null,则找到一个循环,current将位于其中的某个位置。这可以通过在current列表中快速迭代ptr两倍,并且在ptr循环一次之前总会找到一个循环(如果存在)。