判断两个单链表是否相交
单链表中的每一个结点包括一个数据域和一个指针域,那么如果两个单链表相交,即两个链表呈现Y形状。
那么怎么怎来实现这个算法呢???
typedef int ElemType;
typedef struct _Node
{
ElemType data;
struct _Node *next;
}LNode, *LinkList;
想到第一个方法,那就是定义两个指针,内嵌循环,然后从头到尾遍历,具体实现如下:
static LinkList ChainTableCross_1(LinkList list1,LinkList list2)
LinkList p = list1->next;
while(p)
{
q = list->next;
while(q)
{
if(p==q) return p;
q=q->next;
}
p=p->next;
}
return NULL;
这么实现的话我们的时间复杂度就是m*n,即O(n²);
那么,对于这个时间复杂度,我们肯定是不能满意的。
那么接下来就是第二种方法:
如果两个单链表交叉的话,那么他们两的尾结点是在一块的都指向空(根据链表的指针域,交叉后两链表的结点是都相同的);
还是定义两个指针,如果让第一个指针(长链表的那个指针)先跑x个单位(x:长的那个链表的长度减去短的链表的长度),然后两个指针一起跑,两个指针会一起跑到空。那么最后进程结束时它的时间复杂度就是O(n),就达到了我们目的。
那么我们需要解决的就求到两个链表的长度,这个对于大家就很简单了。
static int GetLength(LinkList list)
{
int count = 0;
LinkList p = list ->next;
while(p != NULL)
{
count++;
p = p ->next;
}
return count;
}
那么方法二的具体实现如下:
static LinkList Chain table cross_2(LinkList list1,LinkList list2)
{
int len1 = GetLength(list1);
int len2 = GetLength(list2);
LinkList p = list1->next;
LinkList q = list2->next;
if (len1 >= len2)
{
for(int i=0;i<(len1-len2);i++)
{
p = p->next;
}
}
else
{
for(int i=0;i<(len2-len1);i++)
{
q = q->next;
}
}
while(p!=NULL)
{
if(p==q) return p;
else
{
p = p->next;
q = q->next;
}
}
return NULL;
}