單向鏈表是否存在環,環的起始點

題目和算法:

可見,如果存在環,可以(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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章