求两个单链表的第一个交点(人搜)
来源:互联网 发布:好玩的桌面软件 编辑:程序博客网 时间:2024/05/21 06:29
/************************************************************* * file:find_common_node_of_two_lists.c * brief:找个两个单链表的第一个交点 * yejing@2015.1.20 1.0 creat *************************************************************/ #include <stdio.h> #include <stdlib.h> typedef struct __node_t{struct __node_t* next;int value; }node_t //获取从头开始的两个不同速指针第一次交汇的节点,没有返回NULL node_t* get_cross_node(node_t* phead){if(!phead)return NULL;node_t *one_step, *two_step;one_step = two_step = phead;while(two_step && one_step->next){one_step = one_step->next;two_step = two_step->next->next;if(one_step == two_step)return one_step;}return NULL; } //通过判断尾节点是否相等判断两个链表是否交叉,如果交叉返回长度差并标示那个比较长 int check_no_circle_lists_crossed(node_t* phead_1, node_t* phead_2, int* diff_len, int* bigger_one, node_t* mark){if(!phead_1 || !phead_2 || is_crossed)return;node_t *tmp1, *tmp2;int count1 = 1, count2 = 1;tmp1 = phead1;tmp2 = phead2;while(tmp1->next != mark){++count1; tmp1 = tmp1->next;}while(tmp2->next != mark){++count2; tmp2 = tmp2->next;}if(tmp2 == tmp1){if(count2 <= count1){*diff_len = count1 - count2;*bigger_one = 1;}else{*diff_len = count2 - count1;*bigger_one = 2;}return 1;}return 0; } /* 返回NULL表示没有交点的情况 */ node_t* process(node_t* phead_1, node_t* phead_2){if(!phead_1 || !phead_2)return NULL;int diff_len = 0, bigger_one = 0;node_t *meet_node1, *meet_node2;node_t *tmp1, tmp2;meet_node1 = get_cross_node(phead_1);meet_node2 = get_cross_node(phead_2);//因为是单链表,所以不可能出现一个有环一个无环还相交的情况if((meet_node1 && !meet_node2)||(!meet_node1 && meet_node2)) return NULL;//两个都无环else if(!meet_node1 && !meet_node2){//两个无环单链表如果相交,最后一个节点一定相等。//另外一个办法是将一个头接到另外一个尾上看是不是有环,判断方法与上面类似if(check_no_circle_lists_crossed(phead_1, phead_2, &diff_len, &bigger_one, NULL)){//消除两个链表的长度差tmp1 = phead_1; tmp2 = phead_2;if(1 == bigger_one)while(diff_len-- > 0 && tmp1->next)tmp1 = tmp1->next;elsewhile(diff_len-- > 0 && tmp2->next)tmp2 = tmp2->next;while(tmp1 && tmp2){if(tmp1 == phead2)return phead1;tmp1 = tmp1->next;tmp2 = tmp2->next;}}elsereturn NULL;}//两个链表都有环,如果交叉,则环必定是公共环,入口也必定是一个else{/*先求入环口,而需要先明确的是:1,重合的时候two_step的路程一定是one_step的两倍。2,一旦one_step进入环内,无论如何two_step一定能在一圈之内追上它。假设从起始点到入环口路程为x,截止相遇时在环内走过y,一圈为m,two在圈中走了n次则2(x+y) = x + y + m.n,即 x + y = m.n,即x+y一定是圈的整数倍。所以从x开始再走y的路程,就是入口,同时也是起点到入口的距离。如果同时走,当二者相等时就是入口*/node_t* circle_enter1 = phead_1;node_t* circle_enter2 = phead_2;while(meet_node1 && circle_enter1){if(meet_node1 == circle_enter1)break;meet_node1 = meet_node1->next;circle_enter1 = circle_enter1->next;}while(meet_node2 && circle_enter2){if(meet_node2 == circle_enter2)break;meet_node2 = meet_node2->next;circle_enter2 = circle_enter2->next;}if(circle_enter2 == circle_enter1){//两种情况,1,环入口是第一个的公共点,2,在入环之前就已经重合了//这里可以先用上满没有环的判断办法计算交点if(check_no_circle_lists_crossed(phead_1, phead_2, &diff_len, &bigger_one, circle_enter2)){//消除两个链表的长度差tmp1 = phead_1; tmp2 = phead_2;if(1 == bigger_one)while(diff_len-- > 0 && tmp1->next)tmp1 = tmp1->next;elsewhile(diff_len-- > 0 && tmp2->next)tmp2 = tmp2->next;while(tmp1 && tmp2){if(tmp1 == phead2)return phead1;tmp1 = tmp1->next;tmp2 = tmp2->next;}}else//在环入口之前没有交点,返回环入口点return circle_enter1;}elsereturn NULL;//两个环不相交}return NULL; }
0 0
- 求两个单链表的第一个交点(人搜)
- 求两个单向无环链表的第一个公共交点
- 求两个单链表的交点
- 求两个单链表的交点
- 寻找两个链表的第一个交点-微策略
- 剑指offer--判断两个链表的第一个交点
- 两个单链表,存在交点,求交点
- 判断两个单链表是否相交及找到第一个交点
- 判断两个链表是否相交,若相交,求第一个交点
- 求两个单链表的交点(可能带环)
- 求两个单向链表的交点
- 求两个相交链表的交点
- 求两个单向链表的交点
- 求两个单向链表的交点
- 求两个相交链表的交点
- 求两个单向链表的交点
- js求两个线段的交点
- 如何找相交单链表的第一个交点?
- 【Android入门 二】Activity的理解
- poj1087 网络最大流
- 占位
- 如何在android下使用binder
- libevent学习三
- 求两个单链表的第一个交点(人搜)
- php 自制基于simple_html_dom的爬虫一只v1.0
- HTML----常用HEAD头标
- 周鸿祎对企业的深刻反思,太有借鉴意义了!
- C语言 二叉树相关
- 二维码读取与扫描
- android 帧布局实现跑马灯
- 如何修改单卡和双卡工程的默认数据连接开关
- Fireworks in Montreal