假定采用带头结点的单链表保存单词,当两个单词有相同的后缀时,则可共享相同的后缀存储空间。例如,“loading”和“being”的存储映像如下图所示。
设str1和str2分别指向两个单词所在单链表的头结点,链表结点结构为,请设计一个时间上尽可能高效的算法,找出由str1和str2所指的两个链表共同后缀的起始位置(如图中字符i所在结点的位置p)。要求:
根据设计思想,采用C或C++或Java语言描述算法,关键之处给出注释。
参考答案:
算法实现: typedef struct Node{ char data; struct Node*next; }SNODE; SNODE*findlist(SNODE*str1,SNODE*str2){ int m,n; SNODE*P,*q; m=listlen(str1); /*求str1的长度。O(m)*/ n=listlen(str2); /*求str2的长度。O(n)*/ /*以下3个循环的时间复杂度为:O(max(m,n))*/ for(P=str1;m>n;m--) /*使P指向的链表与q指向的链表等长*/ P=P->next; for(q=str2;m<n;n--) /*使q指向的链表与P指向的链表等长*/ q=q->next; while(p->next!=NULL&&p->next!=q->next){ /*查找共同后缀起始点*/ p=p->next; /*两个指针同步向后移动*/ q=q->next; } return p->next; /*返回共同后缀的起始点*/ } int listlen(SNODE*head){ /*求链表长度*/ int len=0; while(head->next!=NULL){ len++; head=head->next; } return len; }