两个链表的第一个公共结点,三种方法~

来源:互联网 发布:log4j2 java web 编辑:程序博客网 时间:2024/05/20 04:12

题目描述:输入两个链表,找出它们的第一个公共结点。这里的公共结点不是指数据域哦,而是指整个结点,所以可知,如果有第一个公共结点,则后面所有结点都一样,呈现的像是Y;

思路分析:三种方法

第一种方法:蛮力法:从链表1开始遍历,遇到一个结点,就遍历链表2的所有结点,找到相同的停止,不推荐,因为时间复杂度太大;

第二种方法:因为是Y形状,所以从后面找,一直找到不相同的结点的为止,因为没有前继指针,所以需要依靠栈来存储。

第三种方法:第一种方法的改进,找出两个链表的差值,让长的链表先走差值步,然后两个链表一起走,直到遇到合适的为止。

#include<iostream>#include<stack>using namespace std;struct Node{int data;Node *next;};Node* Insert_tail(Node *list,int value)//尾插{if(list == NULL){return NULL;}Node *node = new Node;node -> data = value;node ->next = NULL;Node *p = list;for(;p->next !=NULL;p=p->next );p->next = node;return node;}/////////////第一种方法:蛮力法:从前面开始找,找到相同的停止,不推荐//////////////////Node *GetMix_1(Node *h1,Node *h2){h1 = h1->next;Node *p = h2->next;while(h1!=NULL)//遍历链表1{p  = h2 ->next ;while(p !=NULL)//遍历链表2{if(h1 == p){return h1;}p = p -> next;}h1 = h1 ->next;}return NULL;}//////////////////////第二种方法:从后面找,一直找到不相同的/////////////////////////////////Node *GetMix_2(Node *h1,Node *h2){//因为想从后往前走,但是又没有前继指针,所以,就利用栈;stack<Node *> s1; //栈1,存链表1stack<Node *> s2; //栈2,存链表2;h1 = h1->next ; //去掉头h2 = h2->next ; //去掉头while(h1 != NULL)//往栈1里放东西{s1.push(h1);h1 = h1 -> next;}while(h2!=NULL)//往栈2里放东西{s2.push(h2);h2 = h2->next; }Node *p = s1.top();Node *q = s2.top();Node *s = NULL;while(q == p){s = p; s1.pop(); //更新栈s2.pop();p = s1.top();//一直取栈顶元素q = s2.top();}return s;}////////////////第三种方法:第一种方法的改进,让长的链表先走,然后两个链表一起走///////////////////////////////Node *Item(Node *big,Node *small,int distance);//分函数,长的先走,然后一起走Node *GetMix_3(Node *h1,Node *h2){Node *p = h1 -> next;int num1 = 0; //记录链表1的长度while(p != NULL){num1++;p = p->next ;}int num2 = 0; //记录链表2的长度p = h2 -> next;while(p != NULL){num2++;p = p->next ;}int max = num1 > num2 ? num1 : num2;//找出比较大的一个int distance = 0; //链表1和链表2的差值p = NULL;if(max == num1) //链表1长{distance = num1 - num2;p = Item(h1,h2,distance);//调用分函数}else//链表2长{distance = num2 - num1;p = Item(h2,h1,distance); //调用分函数}return p;}Node *Item(Node *big,Node *small,int distance){while(distance >= 0) //先让长的走distance步{big = big->next ;distance --;}small = small->next ; //去掉短的的头while(big!=NULL && small!=NULL)//两个一起走{if(big == small)//遇到一样的了{return big;}big = big->next;small = small->next;}return NULL;}void CreateList(Node *head1,Node *head2,Node *head3)//创建有公共结点的链表1和链表2;{int arr[] = {1,2,3,4};int brr[] = {5,6};int mix[] = {7,8,9};int lenarr = sizeof(arr)/sizeof(arr[0]);int lenbrr = sizeof(brr)/sizeof(brr[0]);int lenmix = sizeof(mix)/sizeof(mix[0]);Node * h1;Node * h2;Node * h3;for(int i=0;i<lenarr;++i){h1 = Insert_tail(head1,arr[i]); //尾插,链表1为:1 2 3 4}for(int i=0;i<lenbrr;++i){h2 = Insert_tail(head2,brr[i]); //尾插,链表2为:5 6 }for(int i=0;i<lenmix;++i){h3 = Insert_tail(head3,mix[i]); //尾插,链表3为:7 8 9}h1->next = head3->next;//给链表1续链表3,链表1更新为:1 2 3 4 7 8 9h2->next = head3->next;//给链表2续链表3,链表2更新为:5 6 7 8 9}void Show(Node *list)//打印函数{if(list == NULL)return;Node *p = list ->next;for(;p != NULL;p = p->next){cout<<p->data<<" ";}cout<<endl;}void clear(Node **list1,Node **list2,Node *pos)//清除{Node *p1 = *list1;Node *p2 = *list2;for(;p1!=NULL;){Node *q = p1->next;if(q!=pos){p1->next = q->next;delete q;}else{break;}}delete p1;for(;p2!=NULL;){Node *q = p2->next;if(q!=pos){p2->next = q->next;delete q;}else{break;}}delete p2;for(;pos->next!=NULL; ){Node *q = pos->next;pos->next = q->next;delete q;}delete pos;}int main(){Node *head1 = new Node; //创建带头链表1head1 ->next = NULL;Node *head2 = new Node;//创建带头链表2head2 ->next = NULL;Node *head3 = new Node;//创建带头链表3head3 ->next = NULL;CreateList(head1,head2,head3); //创建有公共结点的链表1和链表2;Node *p1 = GetMix_1(head1,head2);if(p1)cout<<p1->data <<endl;Node *p2 = GetMix_2(head1,head2);if(p2)cout<<p2->data <<endl;Node *p3 = GetMix_3(head1,head2);if(p3)cout<<p3->data <<endl;clear(&head1,&head2,p3);return 0;}


原创粉丝点击