17_7_16:判断两个链表是否相交,若相交,求交点。如果链表带环呢?
来源:互联网 发布:windows系统管理书籍 编辑:程序博客网 时间:2024/05/14 08:59
1.【基础题】–1.判断两个链表是否相交,若相交,求交点。(假设链表不带环)2.判断两个链表是否相交,若相交,求交点。(假设链表可能带环)【升级版】
2.【附加题】–请问下面的程序一共输出多少个“-”?
#include <stdio.h>#include <unistd.h>int main(void) { int i; for(i=0; i<2; i++){ fork(); printf("-"); } return 0; }
**
基础题:
**
定义的单链表节点
#include <iostream> //采用C++编译环境。typedef struct ListNode{ int _val; ListNode* _pNext;}Node, *PNode;
在代码中定义的一些函数
//获取环中节点中快慢指针的碰撞点。PNode Get_Impact_Point(PNode pHead);//获取带环链表中环的入口点PNode Get_Entrance_Point(PNode pHead);//判断两个链表是否相交,若相交,求交点。(假设链表不带环)PNode Is_Has_Intersection(PNode pHead_1, PNode pHead_2);//判断两个链表是否相交,若相交,求交点。(假设链表可能带环)【升级版】PNode Is_Has_Intersection_2(PNode pHead_1, PNode pHead_2);
1.判断两个链表是否相交,若相交,求交点。(假设链表不带环)
思路:
不带环的两个链表相交,表示从交节点开始,两个链表中的节点一直相同。
那么两个链表的最后一个节点也相同。可以当做一个判断条件。
如果两个不带环链表相交,则将其中一个链表的头尾节点相连,构成一个带环的单链表。
这样问题就变为了,求带环单链表的环的入口点的问题。
PNode Is_Has_Intersection(PNode pHead_1, PNode pHead_2){ if ((NULL == pHead_1) || (NULL == pHead_2)) //当有空链表时,没有交点。 return NULL; if (pHead_1 == pHead_2) //如果两个链表是通过一个链表的情况。 return pHead_1; PNode pTail_1 = pHead_1; //用来指向pHead_1的尾节点 PNode pTail_2 = pHead_2; //用来指向pHead_2的尾节点 while (pTail_1->_pNext) pTail_1 = pTail_1->_pNext; while (pTail_2->_pNext) pTail_2 = pTail_2->_pNext; if (pTail_1 != pTail_2) //两个链表最后一个节点不相等,说明没有相交。 return NULL; //走到这里,说明pTail_1 = pTail_2。两个链表相交,下面开始求交点。 //将其中一个链表的头结点与尾节点相连。最终两个链表会构成一带环单链表 //问题变为求带环单链表的环的入口了。 //1,将两个单链表变为带环单链表(pHead_2为新的头指针) pTail_1->_pNext = pHead_1; //2,求环的入口。(调用写的函数,前一篇博文已写,后面也会给出) PNode pCross = Get_Entrance_Point(pHead_2); return pCross;}
2.判断两个链表是否相交,若相交,求交点。(假设链表可能带环)【升级版】
思路:
先判断两个链表是否是同一个链表的情况。
1,相同,直接返回头结点。
2,不相同,在往下走。
再判断两个链表是否带环。
1,都不带环—>判断两个不带环单链表是否相交,若相交,求交点。
2,一个带环,一个不带环—->不想交
3,两个链表都带环—->1,交点在环外,2,交点再环内,3,不相交
通过两个链表环的入口点是否相等,来判断交点在环外还是环内。
若相等,则在环外或者就是入口点处。此时相交。–》去掉环,变为求两个不带环单链表求交点交点
若不相等,则判断两个入口点是否在通过一个环中,若在环中,则两个入口点都是交点。否则,不相交。
PNode Is_Has_Intersection_2(PNode pHead_1, PNode pHead_2){ //存在空链表,不存在交点 if ((NULL == pHead_1) || (NULL == pHead_2)) return NULL; //如果两个链表是同一个链表,则直接返回头结点。 if (pHead_1 == pHead_2) return pHead_1; PNode pCross = NULL; //交点 //获取链表快慢指针的碰撞点,如果存在,则说明链表有环 PNode pImpact_1 = Get_Impact_Point(pHead_1); PNode pImpact_2 = Get_Impact_Point(pHead_2); //都不带环--->判断两个不带环单链表是否相交,若相交,求交点。 if ((NULL == pImpact_1) && (NULL == pImpact_2)) { pCross = Is_Has_Intersection(pHead_1, pHead_2); return pCross; } //一个带环,一个不带环---->不相交 if (!pImpact_1 || !pImpact_2) return NULL; //两个链表都带环---->若相交,环是公有的,则判断链表1的碰撞点是否在链表2的环中 //两个链表都带环的情况。 //有三种情况。 //1,不相交。 //2,相交,交点在环外。 //3,相交,交点在环内。 //为了不重复定义变量,浪费空间,暂时用pImpact指向返回的环入口点。 pImpact_1 = Get_Entrance_Point(pHead_1); pImpact_2 = Get_Entrance_Point(pHead_2); //此时,带环链表有可能相交于环内,有可能不相交 if (pImpact_1 != pImpact_2) { PNode pCur = pImpact_2; //作为遍历pHead_2的指针 //需要注意的是,在遍历pHead_2时,如果pHead_1的入口点不在pHead_2的环中,会死循环 //所以,需要从pHead_2的环入口点,开始遍历,直到再次遇到入口点。 while (pCur != pImpact_1) { pCur = pCur->_pNext; if (pCur == pImpact_2) //防止在环内一直遍历,而死循环 break; } //pHead_1的入口点pImpact_1在pHead_2的环中,即相交,随便返回一个入口点 if (pCur == pImpact_1) { return pImpact_1; } else //否则,不相交 { return NULL; } } //pImpact_1 == pImpact_2 //此时,两个链表有一个公共环,并且,节点在环外。--》去掉环的影响,变为求两个不带环单链表求交点问题 PNode pTemp = pImpact_1->_pNext; //记录,环的入口的下一节点。 pImpact_1->_pNext = pHead_1; //去掉旧环,构成一个新环(pHead_2为头结点) //获取新环的入口点,即原来两个链表的交点 pCross = Get_Entrance_Point(pHead_2); //去掉新环,还原旧环 pImpact_1->_pNext = pTemp; return pCross;}
3.下面给出上述两个函数中调用的自定义函数
//获取环中节点中快慢指针的碰撞点。PNode Get_Impact_Point(PNode pHead){ if (NULL == pHead) return NULL; PNode pFast = pHead; //快指针每次走两步 PNode pSlow = pHead; //慢指针每次走一步 while ((NULL != pFast) && (NULL != pFast->_pNext)) { pFast = pFast->_pNext->_pNext; pSlow = pSlow->_pNext; if (pFast == pSlow) break; } if ((NULL == pFast) || (NULL == pFast->_pNext)) //不可使用pFast!=pSlow作为判断条件,当链表只有一个元素时,会出错。 return NULL; return pFast;}
//获取带环链表中环的入口点PNode Get_Entrance_Point(PNode pHead){ PNode pImpact = Get_Impact_Point(pHead); if (NULL == pImpact) //链表中不存在环 return NULL; //头结点到入口点的长度设为:X //环的长度设为R //碰撞点到入口的长度设为:R1 //通过计算(前一篇博文中写有),可以推到出存在某一个n(n为非负整数),使得:X = nR + R1. //所以,头结点和碰撞点同时出发, 最终会在入口点相遇。 while (pImpact != pHead) { pImpact = pImpact->_pNext; pHead = pHead->_pNext; } //此时,两者都在入口点处,返回入口点位置。 return pImpact; }
**
附加题
**
关于fork函数的知识,推荐博文:http://blog.csdn.net/jason314/article/details/5640969
里面对于fork进行了深入的讲解。而且例子也比较好。也包括这个例子。
下面,呈现在ubuntu下运行的结果图。
li
结果打印了6个‘-’
- 17_7_16:判断两个链表是否相交,若相交,求交点。如果链表带环呢?
- 判断两个链表是否相交?若相交,求交点(假设链表带环)
- 判断两个链表是否相交,若相交,求交点。(假设链表带环、不带环)
- 判断两个链表是否相交,若相交,求交点。
- 判断两个链表是否相交,若相交,求交点
- 判断两个链表是否相交,若相交,求交点
- 判断两个链表是否相交,若相交,求交点,若带环呢/fork继承问题
- 判断两个链表是否相交,若相交,求交点,考虑带环情况实现代码
- 判断两个链表是否相交,若相交,求第一个交点
- 判断两个链表是否相交,若相交,求交点:1.不带环。2.有可能带环
- 判断两个链表是否相交并求交点
- 判断单链表是否有环,如果有找出环的入口位置=>求两个相交链表的交点
- 1.判断两个链表是否相交,若相交,求交点。(假设链表不带环)2.判断两个链表是否相交,若相交,求交点。(假设链表可能带环)【升级版】
- 链表--1.判断两个链表是否相交,若相交,求交点。(假设链表不带环)2.判断两个链表是否相交,若相交,求交点。(假设链表可能带环)
- 1.判断两个链表是否相交,若相交,求交点。(假设链表不带环)2.判断两个链表是否相交,若相交,求交点。(假设链表可能带环)【升级版】
- 判断两个链表是否相交,若相交,求交点。(假设链表不带环)(C语言)
- 求两个链表是否相交,若相交,求交点(链表可能带环)
- 判断两链表是否相交,若相交求交点(链表可能带环)
- viewpager+gridView实现分页
- MySQL安装使用遇到的问题
- (MFC)SerialPort类实现串口发送16进制数字
- spark快速大数据分析笔记_1
- 记录
- 17_7_16:判断两个链表是否相交,若相交,求交点。如果链表带环呢?
- Python网络爬虫——Requests第三方库
- Android Wi-Fi Driver(Broadcom)解析
- 论文阅读笔记之Dispnet
- window下go开发环境的搭建
- DrawerLayout和NavigationView轻松实现抽屉侧滑
- Android Wi-Fi 信号强度--SIGNAL_POLL
- Python3 基本数据类型
- 工厂方法模式(Factory Method Pattern)。