Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在单链表中寻找循环_C++_Linked List_Cycle - Fatal编程技术网

C++ 在单链表中寻找循环

C++ 在单链表中寻找循环,c++,linked-list,cycle,C++,Linked List,Cycle,在单链表中查找循环,并查找循环开始的节点。 我看到过使用两个指针来查找循环,通常是缓慢和快速的,但我已经编写了这段代码,它似乎工作得很好。我的问题是,在单链表中查找循环时,我的代码是否遗漏了某些内容 Node* find_cycle_node(Node *head){ Node *p=head; Node *q; while(p->next!=null) { q=p->next; while(q->nex

在单链表中查找循环,并查找循环开始的节点。 我看到过使用两个指针来查找循环,通常是缓慢和快速的,但我已经编写了这段代码,它似乎工作得很好。我的问题是,在单链表中查找循环时,我的代码是否遗漏了某些内容

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
}
我的代码有什么遗漏吗

这行看起来很糟糕,应该改成s.th。像

return NULL; // no cycle detected

如果存在一个循环,即手柄下方的两个节点,则内部循环不会终止,例如,对于类似以下内容,它将是一个无限循环:

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

在我看来,您的内部循环条件似乎不明确。您正在分析p==q,其中q是p->next。这意味着之前考虑的节点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;
}
你认为人们对这个代码有什么看法。

这个怎么样

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
{ //建立一个包含循环的列表

ZNODE* head = new ZNODE(0);
ZNODE* current = head;
ZNODE* cycle = 0;

for (int i = 1; i < 8; i++)
{
    current->_next = new ZNODE(i);
    current = current->_next;

    if (i == 6)
        cycle = current;

    if (i == 7)
        current->_next = cycle;
}

// verify that there is a cycle
ZNODE* slow = head;
ZNODE* fast = head;
ZNODE* cycleNode = 0;

while (slow && fast && fast->_next)
{
    slow = slow->_next;
    fast = fast->_next->_next;

    if (slow == fast)
    {
        cycleNode = slow;
        break;
    }

}

if (cycleNode == 0)
{
    printf("No cycle\n");
    return;
}

// finally find a cycle node which will be p2
ZNODE* p1 = head;
ZNODE* p2 = cycleNode;

while (1)
{
    for (p2 = cycleNode; p2->_next != cycleNode; p2 = p2->_next)
    {
        if (p2 == p1)
            break;          
    }

    if (p2 == p1)
        break;

    p1 = p1->_next;
}

printf("%d\n", p2->_i);

}

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

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将位于其中的某个位置。其工作原理是在列表中以两倍于ptr的速度迭代current,并且在ptr循环一次之前,始终会找到一个循环(如果存在任何循环)。

with return;,您将得到编译错误。如果未检测到周期,则返回NULL此站点不用于代码审查。如果你的代码没有具体的问题你不理解,那么你应该在其他地方请求一般的反馈。嗯,我想你可能要考虑的一件事,不仅是正确性,而且是运行时。你的算法看起来像是在^2上运行的,而我相信双指针一乌龟和兔子运行的时间差不多。@J Trana:我也有类似的想法。但是,如果我仔细观察,它并不完全在^2上。对于外循环的每次迭代,我的内循环减少一个节点。我不是在每次迭代中都运行内部循环'n'次。它可能小于^2。如果空间复杂度被接受,可以有时间复杂度算法。对不起,我没有理解这一点。当指针p到达节点3时,指针q将被设置为节点4,然后是节点5,最后是节点3。现在,我的条件将为true p==q,现在它将返回节点q,即3,程序将终止。@user2773985:在第一次外部迭代中,p位于节点1。q使用节点2初始化,移动到节点3,并无限地继续执行序列4、5、3。它永远不会到达下一个指针为null的节点,也永远不会等于p。哦,好了!我找不到这个错误。太棒了,谢谢,编辑!我没有注意到它,因为它并不重要!但是,很好的发现。再次感谢。您的版本也可能有无限循环。@Jarod42我已经更新了代码。目前这一个不是无限循环的。但我这里的问题是,问这个问题的人在不同的位置引用了相同的数据,因为循环问题来自破解编码面试。我的代码是对相同数据的回答。为了使它成为引用同一节点的循环,我们只需将if条件更改为'ifp==q',这将检查内存位置。如果内存引用相同,则会出现cycle@yashgard1232:OP希望检测格式错误列表的周期。他不想找到重复的值。所以你误解了这个问题。
ZNODE* head = new ZNODE(0);
ZNODE* current = head;
ZNODE* cycle = 0;

for (int i = 1; i < 8; i++)
{
    current->_next = new ZNODE(i);
    current = current->_next;

    if (i == 6)
        cycle = current;

    if (i == 7)
        current->_next = cycle;
}

// verify that there is a cycle
ZNODE* slow = head;
ZNODE* fast = head;
ZNODE* cycleNode = 0;

while (slow && fast && fast->_next)
{
    slow = slow->_next;
    fast = fast->_next->_next;

    if (slow == fast)
    {
        cycleNode = slow;
        break;
    }

}

if (cycleNode == 0)
{
    printf("No cycle\n");
    return;
}

// finally find a cycle node which will be p2
ZNODE* p1 = head;
ZNODE* p2 = cycleNode;

while (1)
{
    for (p2 = cycleNode; p2->_next != cycleNode; p2 = p2->_next)
    {
        if (p2 == p1)
            break;          
    }

    if (p2 == p1)
        break;

    p1 = p1->_next;
}

printf("%d\n", p2->_i);
ptr = head;
current = nullptr;
if (!ptr) {
  current = ptr->next;
  while(current && current!=ptr) {
    current = current->next;
    if (current) {
      current = current->next;
    }
    ptr = ptr->next;
  }
}