链表面试题之链表相交问题
链表相交问题,面试题,链式表2016-06-26
int Check_Cross(pLinkList plist1,pLinkList plist2) { //判断链表是否相交,两个链表均不带环 pLinkNode p1=plist1->phead; pLinkNode p2=plist2->phead; if((p1 == NULL)||(p2 == NULL)) //空链表 { return -1; } while(p1->next) { p1=p1->next; } while(p2->next) { p2=p2->next; } //p1,p2分别指向链表plist1,plist2的最后一个结点 //通过判断最后一个结点是否相同来判断两条链表是否相交 if(p1 == p2) return 1; //相交 return 0; } pLinkNode GetLink_EntryNode(pLinkList plist1,pLinkList plist2) { //统计出两个链表的结点总数count1,count2 //让较长的链表走count1-count2步 //两个链表一起走直到相遇则返回相遇结点的地址 int count1=0; int count2=0; pLinkNode cur1=NULL; pLinkNode cur2=NULL; assert(plist1); assert(plist2); cur1=plist1->phead; cur2=plist2->phead; while(cur1) //统计链表1的总结点数 { count1++; cur1=cur1->next; } while(cur2) //统计链表2的总结点数 { count2++; cur2=cur2->next; } cur1=plist1->phead; cur2=plist2->phead; if(count1-count2 >= 0) { while(count1-count2 != 0) { cur1=cur1->next; count1--; } if(cur1 != cur2) { cur1=cur1->next; cur2=cur2->next; } } else { while(count2-count1 != 0) { cur2=cur2->next; count2--; } if(cur1 != cur2) { cur1=cur1->next; cur2=cur2->next; } } return cur1; } pLinkNode _GetLink_EntryNode(pLinkList plist1,pLinkList plist2) { //构造成环的方法求两个链表的交点 pLinkNode meet=NULL; pLinkNode cur=NULL; assert(plist1); assert(plist2); cur=plist1->phead; //构造环 while(cur->next) { cur=cur->next; } cur->next=plist2->phead; //找出环的相遇结点 meet=Check_Cycle(plist1); //求出环的入口点 return GetCircle_EntryNode(plist1,meet); }
int _Check_Cross(pLinkNode meet1,pLinkNode meet2) //两条链表都带环判断链表是否相交 { pLinkNode m1=meet1; pLinkNode m2=meet2; while(m1 != m2) { m1=m1->next; } if(m1 == m2) return 1;//链表相交 return 0; } pLinkNode EntryNode(pLinkList plist1,pLinkList plist2,pLinkNode start1) { pLinkNode s=start1; pLinkNode meet=NULL; assert(plist1); assert(plist2); while(s->next != start1) { s=s->next; } s->next=plist2->phead; meet=Check_Cycle(plist1); return GetCircle_EntryNode(plist1,meet); }
void text10() { int ret=0; LinkList plist1; LinkList plist2; pLinkNode meet1=NULL; pLinkNode meet2=NULL; pLinkNode start1=NULL; pLinkNode start2=NULL; pLinkNode tmp=NULL; Init_LinkList(&plist1); Push_back(&plist1,1); Push_back(&plist1,3); Push_back(&plist1,5); Push_back(&plist1,7); Push_back(&plist1,9); Push_back(&plist1,11); Find_NUM(&plist1,11)->next=Find_NUM(&plist1,5); //链表1构造成环 Init_LinkList(&plist2); Push_back(&plist2,2); Push_back(&plist2,4); //Find_NUM(&plist2,4)->next=Find_NUM(&plist1,7); //交点在环内 Find_NUM(&plist2,4)->next=Find_NUM(&plist1,3); //交点在环外 //1 //Init_LinkList(&plist1); //两条链表都不带环 //Push_back(&plist1,9); //Push_back(&plist1,1); //Push_back(&plist1,3); //Push_back(&plist1,5); //Push_back(&plist1,7); //printf("链表1的元素为:"); //Print_LinkList(&plist1); //2 //Init_LinkList(&plist2); //Push_back(&plist2,2); //链表2与链表1公用同交点以后的结点 //Find_NUM(&plist2,2)->next=Find_NUM(&plist1,3); //printf("链表2的元素为:"); //Print_LinkList(&plist2); meet1=Check_Cycle(&plist1); meet2=Check_Cycle(&plist2); if(meet1 == NULL && meet2 == NULL) { //两条链表都不带环 ret=Check_Cross(&plist1,&plist2); if(ret == 1) { printf("两个链表相交\n"); //tmp=GetLink_EntryNode(&plist1,&plist2); tmp=_GetLink_EntryNode(&plist1,&plist2); printf("链表的相交点为:%d\n",tmp->data); } else if(ret == 0) { printf("两个链表不相交\n"); } else { printf("存在空链表\n"); } } else if((meet1 == NULL && meet2 != NULL) || (meet1 != NULL && meet2 == NULL)) { //一条链表带环一条链表不带环 printf("两个链表不相交\n"); } else { //两条链表都带环 ret=_Check_Cross(meet1,meet2); if(ret == 1) { printf("两个链表相交\n"); start1=GetCircle_EntryNode(&plist1,meet1); start2=GetCircle_EntryNode(&plist2,meet2); if(start1 == start2) //交点在环外 { tmp=EntryNode(&plist1,&plist2,start1); printf("链表的相交点为:%d\n",tmp->data); } else //交点在环内 { printf("链表的相交点为:%d\n",start2->data); } } else { printf("两个链表不相交\n"); } } free(meet1); free(meet2); }