题目描述:
输入两个链表,找出它们的第一个公共结点。
方法一:分别把两个链表的结点放入两个栈中,这样两个链表的尾结点就位于两个栈的栈顶,接下来比较两个栈顶的结点是否相同。如果相同,则把栈顶弹出接着比较下一个栈顶,知道找到最后一个不相同的结点。需要用到两个辅助栈,空间复杂度是O(m+n)时间复杂度也是O(m+n).
方法二:首先遍历两个链表得到他们的长度,就能知道哪个链表比较长,以及长的链表比短的链表多几个结点. 在第二次遍历的时候,在较长的链表上先走若干步,接着再同时在两个链表上遍历,找到的第一个相同的结点就是它们的第一个公共结点。空间复杂度O(1),时间复杂度O(m+n).
代码实现:
#include <stdio.h>
#include <malloc.h>
typedef struct node
{
int value;
struct node *next;
}LinkList;
//得到链表的长度
int GetLength(LinkList *L)
{
int count=0;
LinkList *p=L;
while(p!=NULL)
{
++count;
p=p->next;
}
return count;
}
LinkList* FindFirstCommonNode(LinkList* pHead1, LinkList* pHead2)
{
//得到两个链表的长度
unsigned int nLength1 = GetLength(pHead1);
unsigned int nLength2 = GetLength(pHead2);
int nLengthDif = nLength1 - nLength2;
LinkList* pListHeadLong = pHead1;
LinkList* pListHeadShort = pHead2;
if(nLength2 > nLength1)
{
pListHeadLong = pHead2;
pListHeadShort = pHead1;
nLengthDif = nLength2 - nLength1;
}
//先在长链表上走几步,再同时在两个链表上遍历
for(int i = 0; i < nLengthDif; ++i)
pListHeadLong = pListHeadLong->next;
while(pListHeadLong != NULL && pListHeadShort != NULL && pListHeadLong->value != pListHeadShort->value)//一起走
{
pListHeadLong = pListHeadLong->next;
pListHeadShort = pListHeadShort->next;
}
//得到第一个公共结点
LinkList* pFirstCommonNode = pListHeadLong;
return pFirstCommonNode;
}
//创建带头结点的单链表
void CreateList(LinkList *L)
{
int data;
LinkList *p=NULL,*q=L; //p指向新分配的结点,始终指向链表的尾部
printf("input the data: ");
while(scanf("%d",&data) !=EOF)
{
p=(LinkList*)malloc(sizeof(LinkList));
p->value=data;
p->next=NULL;
q->next=p;
q=p;
}
}
//输出单链表
void output(LinkList *L)
{
LinkList *p=L->next;
while(p!=NULL)
{
printf("%d\t",p->value);
p=p->next;
}
}
void main()
{
LinkList* L1 = (LinkList*)malloc(sizeof(LinkList));
LinkList* L2 = (LinkList*)malloc(sizeof(LinkList));
CreateList(L1);
CreateList(L2);
int commonData = FindFirstCommonNode(L1->next, L2->next)->value;
printf("两个链表的第一个公共结点为%d\n", commonData);
}