两个链表的第一个公共结点,三种方法~

题目描述:输入两个链表,找出它们的第一个公共结点。这里的公共结点不是指数据域哦,而是指整个结点,所以可知,如果有第一个公共结点,则后面所有结点都一样,呈现的像是Y;

思路分析:三种方法

第一种方法:蛮力法:从链表1开始遍历,遇到一个结点,就遍历链表2的所有结点,找到相同的停止,不推荐,因为时间复杂度太大;

第二种方法:因为是Y形状,所以从后面找,一直找到不相同的结点的为止,因为没有前继指针,所以需要依靠栈来存储。

第三种方法:第一种方法的改进,找出两个链表的差值,让长的链表先走差值步,然后两个链表一起走,直到遇到合适的为止。

#include<iostream>
#include<stack>
using namespace std;

struct Node
{
	int data;
	Node *next;
};

Node* Insert_tail(Node *list,int value)//尾插
{
	if(list == NULL)
	{
		return NULL;
	}
	Node *node = new Node;
	node -> data = value;
	node ->next = NULL;
	Node *p = list;
	for(;p->next !=NULL;p=p->next );
	p->next = node;
	return node;
}
/////////////第一种方法:蛮力法:从前面开始找,找到相同的停止,不推荐//////////////////
Node *GetMix_1(Node *h1,Node *h2)
{
	h1 = h1->next;
	Node *p = h2->next;
	while(h1!=NULL)//遍历链表1
	{
		p  = h2 ->next ;
		while(p !=NULL)//遍历链表2
		{
			if(h1 == p)
			{
				return h1;
			}
			p = p -> next;
		}
		h1 = h1 ->next;
	}
	return NULL;
}
//////////////////////第二种方法:从后面找,一直找到不相同的/////////////////////////////////
Node *GetMix_2(Node *h1,Node *h2)
{
	//因为想从后往前走,但是又没有前继指针,所以,就利用栈;
	stack<Node *> s1; //栈1,存链表1
	stack<Node *> s2; //栈2,存链表2;
	h1 = h1->next ; //去掉头
	h2 = h2->next ; //去掉头
	while(h1 != NULL)//往栈1里放东西
	{
		s1.push(h1);
		h1 = h1 -> next;
	}
	while(h2!=NULL)//往栈2里放东西
	{
		s2.push(h2);
		h2 = h2->next; 
	}
	Node *p = s1.top();
	Node *q = s2.top();
	Node *s = NULL;
	while(q == p)
	{
		s = p; 
		s1.pop(); //更新栈
		s2.pop();
		p = s1.top();//一直取栈顶元素
		q = s2.top();
	}
	return s;
}
////////////////第三种方法:第一种方法的改进,让长的链表先走,然后两个链表一起走///////////////////////////////
Node *Item(Node *big,Node *small,int distance);//分函数,长的先走,然后一起走
Node *GetMix_3(Node *h1,Node *h2)
{
	Node *p = h1 -> next;
	int num1 = 0; //记录链表1的长度
	while(p != NULL)
	{
		num1++;
		p = p->next ;
	}
	int num2 = 0; //记录链表2的长度
	p = h2 -> next;
	while(p != NULL)
	{
		num2++;
		p = p->next ;
	}
	int max = num1 > num2 ? num1 : num2;//找出比较大的一个
	int distance = 0; //链表1和链表2的差值
	p = NULL;
	if(max == num1) //链表1长
	{
		distance = num1 - num2;
		p = Item(h1,h2,distance);	//调用分函数
	}
	else//链表2长
	{
		distance = num2 - num1;
		p = Item(h2,h1,distance); //调用分函数
	}
	return p;
}

Node *Item(Node *big,Node *small,int distance)
{
		while(distance >= 0) //先让长的走distance步
		{
			big = big->next ;
			distance --;
		}
		small = small->next ; //去掉短的的头
		while(big!=NULL && small!=NULL)//两个一起走
		{
			if(big == small)//遇到一样的了
			{
				return big;
			}
			big = big->next;
			small = small->next;
		}
		return NULL;
}


void CreateList(Node *head1,Node *head2,Node *head3)//创建有公共结点的链表1和链表2;
{
	int arr[] = {1,2,3,4};
	int brr[] = {5,6};
	int mix[] = {7,8,9};
	int lenarr = sizeof(arr)/sizeof(arr[0]);
	int lenbrr = sizeof(brr)/sizeof(brr[0]);
	int lenmix = sizeof(mix)/sizeof(mix[0]);
	Node * h1;
	Node * h2;
	Node * h3;
	for(int i=0;i<lenarr;++i)
	{
		h1 = Insert_tail(head1,arr[i]); //尾插,链表1为:1 2 3 4
	}
	for(int i=0;i<lenbrr;++i)
	{
		h2 = Insert_tail(head2,brr[i]); //尾插,链表2为:5 6 
	}
	for(int i=0;i<lenmix;++i)
	{
		h3 = Insert_tail(head3,mix[i]); //尾插,链表3为:7 8 9
	}
	h1->next = head3->next;//给链表1续链表3,链表1更新为:1 2 3 4 7 8 9
	h2->next = head3->next;//给链表2续链表3,链表2更新为:5 6 7 8 9
}

void Show(Node *list)//打印函数
{
	if(list == NULL)
		return;
	Node *p = list ->next;
	for(;p != NULL;p = p->next)
	{
		cout<<p->data<<" ";
	}
	cout<<endl;
}

void clear(Node **list1,Node **list2,Node *pos)//清除
{
	Node *p1 = *list1;
	Node *p2 = *list2;
	for(;p1!=NULL;)
	{
		Node *q = p1->next;
		if(q!=pos)
		{
			p1->next = q->next;
			delete q;
		}
		else
		{
			break;
		}
	}
	delete p1;
	for(;p2!=NULL;)
	{
		Node *q = p2->next;
		if(q!=pos)
		{
			p2->next = q->next;
			delete q;
		}
		else
		{
			break;
		}
	}
	delete p2;
	for(;pos->next!=NULL; )
	{
		Node *q = pos->next;
		pos->next = q->next;
		delete q;
	}
	delete pos;
}
int main()
{
	Node *head1 = new Node; //创建带头链表1
	head1 ->next = NULL;
	Node *head2 = new Node;//创建带头链表2
	head2 ->next = NULL;
	Node *head3 = new Node;//创建带头链表3
	head3 ->next = NULL;
	CreateList(head1,head2,head3); //创建有公共结点的链表1和链表2;
	Node *p1 = GetMix_1(head1,head2);
	if(p1)
		cout<<p1->data <<endl;
	Node *p2 = GetMix_2(head1,head2);
	if(p2)
		cout<<p2->data <<endl;
	Node *p3 = GetMix_3(head1,head2);
	if(p3)
		cout<<p3->data <<endl;
	clear(&head1,&head2,p3);
	return 0;

}


原创文章 88 获赞 21 访问量 3万+

猜你喜欢

转载自blog.csdn.net/cfy1024/article/details/77856168
今日推荐