題目和算法:
可見,如果存在環,可以(1)判斷有環(2)求出環的大小(3)輸出環的起始位置。算法在上面鏈接中已經說的很清楚了,我主要實現用
快慢指針 和 結構體位標記
來求出(1)和(3)。
代碼:
#include<stdio.h>
#include<stdlib.h>
typedef struct node{
int no;
struct node * next;
}Node;
#define N 50
#define DEAD 34
#define MAX 200
int generate_link_with_circle(Node ** header)
{
int i;
Node * pre = NULL;
Node * circle_entrace = NULL;
for(i=0;i<N-1;i++){
Node * tmp = (Node *)malloc(sizeof(Node));
tmp->no = i;
tmp->next = NULL;
if(i==0){
*header = tmp;
}else{
pre->next = tmp;
}
pre = tmp;
if(i == DEAD)
circle_entrace = tmp;
}
Node * last = (Node *)malloc(sizeof(Node));
last->no = i;
last->next = circle_entrace;
pre->next = last;
return 0;
}
int print_link(Node * header)
{
int max_print_num = 0;
Node * tmp = header;
while(max_print_num<MAX && tmp->next!=NULL){
printf("%2d ",tmp->no);
max_print_num++;
tmp = tmp->next;
}
printf("\n");
return 0;
}
int find_circle_entrance(Node * header,Node ** entrance)
{
Node * slow;
Node * fast;
Node * meet;
if(NULL==header->next || NULL==header->next->next)
return 0;
slow = header->next;
fast = header->next->next;
while(1){
if(fast->next==NULL || fast==NULL){
*entrance = NULL;
return 0;
}
if(fast == slow){
meet = fast;
fast = header;
while(1){
if(fast == slow){
*entrance = fast;
break;
}
slow = slow->next;
fast = fast->next;
}
return 1;
}
slow = slow->next;
fast = fast->next->next;
}
return 1;
}
int find_circle_entrance_2(Node * header,Node ** entrance)
{
Node * tmp = header;
int size = sizeof(Node);
char * ch = NULL;
while(1){
if(tmp->next == NULL)
return 0;
//mark
ch = tmp;
ch = tmp+size-1;
*ch = (*ch) | 0x01;
//check
ch = tmp->next+size-1;
if(0x01 == (*ch & 0x01 )){
*entrance = tmp->next;
return 1;
}
tmp = tmp->next;
}
}
int main()
{
Node * header;
generate_link_with_circle(&header);
// print_link(header);
Node * entrance = NULL;
find_circle_entrance_2(header,&entrance);
if(entrance == NULL){
printf("no circle.\n");
}else{
printf("dead! the entrance is %d.\n",entrance->no);
}
return 0;
}