I'm trying to implement a program for finding a starting node of circular linked list. My code is-
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;
}
ths is my code. I'm not getting any value in return t->data part or I'm unable to find the start node of cycle ink list.Any help?
2 Answers 2
t = t->link->link; // t->link can be null
//so t = t->link->link can be a crash or illegal reference
Change the loop to:
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;
}
}
I have gone through your code. Comparing with the algorithm discussion here it seems to be OK. But you are returning a char why dont you return a pointer so that you can check if it is NULL or not. In case it is not null then issue pt->tada. This makes more sense.
I checked you code it seems you are not implementing circular linked list correctly in Append(). I am providing you with a working implementation below. See how I modified 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;
}
Please note that Display function is also wrong as runs an infinite loop of the linked list is circular. I have not modified it since it is not relevant to you question. Thanks.
5 Comments
...
p = NULL;
char num;
Append(&p,'A');
...
You are trying to assign to NULL, which Append handles, but you are doing it repeatedly, which means you won't make a list, just a bunch of dangling nodes.
You need to make one node to start, outside of append, as your seed node, and pass that in.
NULLdereference that seems to be leading to this question, then it appears that you might get stuck in the lastwhileloop withrendlessly chasingt.*qhas a pointer to some node, and the one you want is the one before it ?Floyd's cycle-finding algorithmAKAthe tortoise and the hare algorithm. You can read about it here.