循环链表的循环开始节点

时间:2013-01-15 02:02:35

标签: c++ c algorithm data-structures

我正在尝试实现一个程序来查找循环链表的起始节点。我的代码是 -

struct node
{
char data;
struct node *link;
} ;

char FindStartNode(struct node **q)
{
    struct node *r,*t;
 r = *q; 
 t = *q;
 while(t->link != NULL)
 {
     r = r->link;
     t = t->link->link;
     if(r == t)
     {
         break;
     }
 }
 if(t == NULL )
     return NULL;
 r = *q;
 while(r != t)
 {
     t = t->link;
     r = r->link;
 }
 return t->data;
}


int main()
{
struct node *p;
p = NULL;
char num;
Append(&p,'A');
Append(&p,'B');
Append(&p,'C');
Append(&p,'D');
Append(&p,'E');
Append(&p,'C');
Display(p);
 num = FindStartNode(&p);
printf("\nStarting node of the cycle linked list is:- %c",num);
_getch();
return 0;
}


int Append(struct node **q, char data)
{
struct node *r,*t;
r = (struct node *)malloc(sizeof(struct node));
r->data = data;
r->link = NULL;
if(*q == NULL)
    *q = r;
else
{
  t = *q;
  while(t->link != NULL)
  {
      t = t->link;
  }
  t->link = r;
    }
return 0;
}
int Display(struct node *q)
{
while(q != NULL)
{
    printf("%c\t",q->data);
    q = q->link;
}
return 0;
}
这是我的代码。我没有得到任何回报t->数据部分或我无法找到循环墨水列表的起始节点。任何帮助?

2 个答案:

答案 0 :(得分:3)

 t = t->link->link; // t->link can be null 
   //so t = t->link->link can be a crash or illegal reference

将循环更改为:

 while(t != NULL)
 {
     r = r->link;
     t = t->link;
     if(t == NULL)
       break; // or return no circle
     else t = t->link;
     if(r == t)
     {
         break;
     }
 }

我已经完成了你的代码。与算法讨论here相比,似乎没问题。但是你返回char为什么不返回一个指针,以便你可以检查它是否为NULL。如果它不为null,则发出pt-> tada。这更有意义。

我检查了你的代码,似乎你没有在Append()中正确实现循环链​​表。我在下面为您提供工作实施。了解我如何修改Append()

#include <stdio.h>
#include <stdlib.h>

struct node
{
char data;
struct node *link;
} ;

char FindStartNode(struct node **q)
{
    struct node *r,*t;
 r = *q;
 t = *q;
 while(t->link != NULL)
 {
     r = r->link;
     t = t->link->link;
     if(r == t)
     {
         break;
     }
 }
 if(t == NULL )
     return NULL;
 r = *q;
 while(r != t)
 {
     t = t->link;
     r = r->link;
 }
 return t->data;
}

int Append(struct node **q, char data);
int main()
{
struct node *p;
p = NULL;
char num;
Append(&p,'A');
Append(&p,'B');
Append(&p,'C');
Append(&p,'D');
Append(&p,'E');
Append(&p,'C');
//Display(p);
 num = FindStartNode(&p);
printf("\nStarting node of the cycle linked list is:- %c\n",num);
//_getch();
return 0;
}

int Append(struct node **q, char data)
{

struct node *r,*t, *startOfcycle=NULL;
r = (struct node *)malloc(sizeof(struct node));
r->data = data;


r->link = NULL;
if(*q == NULL)
    *q = r;
else
{
  t = *q;
  while(t->link != NULL)
  {
      if(t->data == data)
         startOfcycle = t;

      t = t->link;
  }


  if(startOfcycle == NULL)
  t->link = r;
  else {// there is a cycle point to the start of cycle
     t->link = startOfcycle;
     free(r);
  }
    }
return 0;
}
int Display(struct node *q)
{
while(q != NULL)
{
    printf("%c\t",q->data);
    q = q->link;
}

请注意Display函数也是错误的,因为链表的无限循环是圆形的。我没有修改它,因为它与你的问题无关。感谢。

答案 1 :(得分:0)

...

 p = NULL;
 char num;
 Append(&p,'A');

...

您正在尝试分配给NULL,其中Append处理,但您正在重复执行,这意味着您不会创建列表,只是一堆悬空节点。

您需要将一个节点作为种子节点开始,在追加之外,然后传入。