
/*
存在这样一种情况,如果两个单词有相同的后缀,那我们可以将后缀作为公共部分存储,比如being和loading,其中ing就可以作为
公共部分,现在存在两个链表,含有公共部分,设计一个高效算法找到其公共后缀其实位置。
分析:
我们可以这样想,如果我们单纯的让两条链表的指针同步移动,那么只有两条链表长度相同时才可能在公共部分的起始位置相遇,
所以我们应该让他们处于同一起跑线上,故而我们应该让较长的链表先走,具体走多少,应该是走过两条链表的长度之差。
*/
struct Link {
union
{
int data;
char letter;
};
Link *next;
};
#include <stdio.h>
#include <stdlib.h>
Link *findCommonSuffix(Link *h1,Link *h2) {
struct Link *p = h1->next, *q = h2->next;
int countP =0, countQ = 0,gap;
while (p) {//遍历,获取链表长度
countP++;
p = p->next;
}
while (q) {
countQ++;
q = q->next;
}
if (countQ>countP) {//让p指针始终指向较长的那条链表
p = h2->next;
q = h1->next;
gap = countQ - countP;
}
else {
p = h1->next;
q = h2->next;
gap = countP - countQ;
}
while (gap--) p = p->next;//长链表指针先行移动gap位
while (q != p && q != NULL) {//当两指针不同或不为NULL时继续向后移动
q = q->next;
p = p->next;
}
return p;
}
int main() {
struct Link *h1,*h2,*com,*p1,*p2,*start;
Link *createLink(int);
char p[] = "letter";//数据类型,char
h1 = createLink(1);
h2 = createLink(1);
com = createLink(1);//公共部分
p1 = h1->next;
p2 = h2->next;
while (p1->next)p1 = p1->next;//到达链尾
while (p2->next)p2 = p2->next;
p1->next = com->next;//链接公共部分
p2->next = com->next;
p1 = h1->next;
p2 = h2->next;
while (p1) {
printf("%c",p1->letter);
p1 = p1->next;
}
printf("\n");
while (p2) {
printf("%c",p2->letter);
p2 = p2->next;
}
printf("\n");
start=findCommonSuffix(h1,h2);
printf("%c",start->letter);
return 0;
}