交叉链表 循环链表

///
//
//  Description:  this file process the link
//  1. add node in the head and the tail
//  2. link has a loop or not 
//  3. two links will meet each other or not
//
///
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <limits.h>


typedef struct NODE
{
	int    data;
	struct NODE * next;
}Node, * Link;


Link head = NULL;


void add_node_in_head(Node * node)
{
	if(head == NULL)// when head of link is NULL
	{
		head = node;
		node->next = NULL;
	}else{
		node->next = head;
		head = node;
	}
}




// add the node in the tail
void add_node_in_tail(Node * node)
{
	Node * p = NULL;
	Node * pre =NULL;
	for(p=head; p!=NULL; p=p->next)
	{
		pre = p;
		// when p points to NULL,
		// p already has no relative with the link,
		// so we shoule record the pre node of p!
	}
	pre->next = node;
	node->next = NULL;


}


// display it
void display_node()
{
	Node * p = head;
	for(; p!=NULL; p = p->next)
	{
		printf("%d ",p->data);
	}
	printf("\n");
}
// travel the link and free the memory
void free_link()
{
	Node * p = head;
	for(; p!=NULL; p=p->next) // remember it is p=p->next,not p++
	{
		free(p);
	}
}



//  the head is a parameter
///


// add a node to link--head
Link add_node(Link head,Node * node)
{
	if(head == NULL)
	{
		head = node;
		node->next = NULL;
	}else{
		node->next = head;
		head = node;
	}
	return head;
}


void travel_display_free_link(Link head)
{
	for(Node * p=head; p!=NULL; p=p->next)
	{
		printf("%d ",p->data);
		//free(p);
	}
	printf("\n");
}


void make_loop(Link head)
{
	Node * tmp;
	int cnt = 0;
	for(Node * p=head; p!=NULL; p=p->next)
	{
		cnt++;
		if(cnt == 7)
			tmp = p;
		if(cnt == 10)
		{
			p->next = tmp;
			break;
		}
	}
}
// one link travels by two steps at a time,
// the other travels by one step at a time,
// the first one(two steps) will get the loop first,
// and it will loop there,waiting the slow one,
// so if there is a loop there,they alway meet each other.
bool loop_link(Link head,Node ** tail,Node ** meet)
{
	Node * one_step = head;
	Node * two_step = head;


	if(one_step == NULL || one_step->next == NULL)// only two node,never has a loop
		return false;


	Node * record_tail = NULL;
	do{
		one_step = one_step->next;
		record_tail = two_step->next;
		two_step = two_step->next->next;
	}while(two_step != NULL && two_step->next != NULL && one_step != two_step);


	if(one_step == two_step)
	{
		(*meet) = two_step;
		return true;
	}else if(two_step == NULL){
		(*tail) = record_tail;
		return false;
	}else if(two_step->next == NULL){
		(*tail) = two_step;
//		(*tail) = one_step->next;
		return false;
	}
}


void make_cross(Link link_one,Link link_two)
{
	link_one->next = link_two->next->next;
}


bool cross_links(Link link_one,Link link_two)
{
	Node * tail = NULL;
	Node * meet = NULL;
	Node * tail_second = NULL;
	Node * meet_second = NULL;


	bool is_loop = false;
	bool is_loop_second = false;


	is_loop = loop_link(link_one,&tail,&meet);
	is_loop_second = loop_link(link_two,&tail_second,&meet_second);
	
	if(!is_loop && !is_loop_second)// both have no loop
	{
		if(tail == tail_second)// when both tails are the same,they're cross
			return true;
		else
			return false;
	}else if(is_loop != is_loop_second){// one has loop,no cross 
		return false;
	}else{// both have cross,mean if they meet each other,the meeting point is beginning of the loop,we can go through the loop by one link,if meet the other loop point(meet_point),they are cross 
		if(meet == meet_second)//it's meeting point
			return true;
		Node * tmp = meet->next;
		while(tmp != meet)// ok,still in the loop
		{
			if(tmp == meet_second)
				return true;
			tmp = tmp->next;
		}
		return false;
	}
}
int main(void)
{
	Node * new_node = NULL;
	for(int i=0; i<100; i++)
	{
		new_node = (Node *)malloc(sizeof(Node));
		new_node->data = i;
		add_node_in_head(new_node);
	}
	
	for(int i=0; i<100; i++)
	{
		new_node = (Node *)malloc(sizeof(Node));
		new_node->data = i;
		add_node_in_tail(new_node);
	}


	display_node();


	free_link();
	
	//  the head is a parameter
	///
	Node * link = NULL;
	for(int i=0; i<11; i++)
	{
		Node * new_node = (Node *)malloc(sizeof(Node));
		new_node->data = 10 * i;
		link = add_node(link,new_node);
	}


	Node * link2 = NULL;
	for(int i=0; i<11; i++)
	{
		Node * new_node = (Node *)malloc(sizeof(Node));
		new_node->data = 10 * i;
		link2 = add_node(link2,new_node);
	}


	travel_display_free_link(link);
	travel_display_free_link(link2);


	make_loop(link);
	make_loop(link2);


	make_cross(link,link5);
	Node * meet_node = (Node *)malloc(sizeof(Node));
	Node * tail_node = (Node *)malloc(sizeof(Node));
	meet_node->data = INT_MAX;
	tail_node->data = INT_MAX;
	printf("%d\n",loop_link(link,&tail_node,&meet_node));
	printf("%d\n",loop_link(link2,&tail_node,&meet_node));


	printf("%d\n",cross_links(link,link2));
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值