单链表第二十二题(寻找公共后缀)

 22.假定采用带头节点的单链表保存单词,当两个单词有相同的后缀时,

       可共享相同的后缀存储空间,例如,“loading”和“being”的存储映像如下图所示。

 设str1和str2分别指向两个单词所在单链表的头结点,链表结点结构为

             data

        next

请设计一个时间上尽可能高效的算法,找出由str1和str2所指向两个链表共同后缀

的起始位置(如图中字符i所在结点的位置p),要求:

1)给出算法的基本设计思想。

2)根据设计思想,采用C或C++或java语言描述算法,关键支出给出注释。

3)说明你所设计算法的时间复杂度。

/*

     存在这样一种情况,如果两个单词又相同的后缀,那我们可以将后缀作为公共部分存储,

     比如being和loading,其中ing就可以作为公共部分,

      现在存在两个链表,含有公共部分,设计一个高效算法找到其公共后缀真实位置。

      分析:

               我们可以这样想,如果我们单纯的让两条链表的指针同步移动,

               那么只有两条链表长度相同时才有可能在公共部分的起始位置相遇,

               所以我们应该让它们处于同一起跑线上,故而我们应该让较长的链表先走,

                具体走多少,应该是走过两条链表的长度之差。

*/

#include<stdio.h>

#include<stdlib.h>

#include "linkStruct.h"//通过自创建头文件引入结构体,ctrl+鼠标左键即可查看

Link  *findCommonSuffix(Link  *h1,Link,  h2){

         Link  *p=h1->next,*q=h2->next;

         int  countP=0,countQ=0,gao;

         while(p){//遍历,获取链表长度

                    countP++;

                     p=p->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(){

         Link   *h1,  *h2,*com,*p1,*p2,*start;

         Link    *createLink(int);

         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->data);

                   p1=p1->next;

            }

           printf("\n");

            while(p2){//打印链表

                          printf("%c",p2->data);

                           p2=p2->next;        

               }      

               printf("\n");

               strat=findCommonSuffix(h1,h2);//寻找公共后缀

               printf("%c",start->data);//打印公共后缀起始节点值

               return    0;

       }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值