两个链表的第一个公共节点
来源:互联网 发布:足彩数据分析推荐 编辑:程序博客网 时间:2024/06/07 09:13
题目:输入两个链表,找出它们的第一个公共节点。链表节点定义如下:
typedef int DataType;typedef struct Node{ DataType data; struct Node *next;}Node, *pList, *pNode;
【方案】由于单向链表的节点只有一个next,所以从第一个节点开始,之后的所有节点都是重合不分叉的,如下图所示。
方案一:在第一条链表上遍历每个节点,每遍历到一个节点就到第二条链表上遍历整条链表,如果两条链表在一个节点上重合,这点即为公共节点,时间复杂度为O(mn)。
方案二:先把两条链表放在两个栈中,这样两条链表的尾节点就位于两个栈的顶部,然后比较两个栈顶的节点。如果相同,则把栈顶弹出再比较下一个栈顶,直到找到最后一个节点。时间复杂度和空间复杂度都是O(m+n),与方案一相比时间效率提高了,但是消耗了一定的空间。
方案三: 第一次遍历两条链表得到它们的长度,及算出长度差;第二次先在长链表上走长度差步,再同时遍历,第一个结合点即为所求。与方案二相比,时间复杂度都是O(m+n),但是不需要辅助栈,提高了空间效率。
【解题思路】
1、求两条链表的长度及链表长度差。
2、在长链表上走“链表长度差”步。
3、同时遍历长短两条链表。
4、得到第一个公共节点
【代码】
unsigned int GetListLength(pList phead){ unsigned int length = 0; pNode pnode = phead; while (pnode != NULL) { ++length; pnode = pnode->next; } return length;}pNode ListFirstCommomNode(pList phead1, pList phead2){ //求两条链表的长度及链表长度差 unsigned int length1 = 0; length1 = GetListLength(phead1); unsigned int length2 = 0; length2 = GetListLength(phead2); int lengthdif = length1 - length2; pList plistlong = phead1; pList plistshort = phead2; if (length1 < length2) { plistlong = phead2; plistshort = phead1; lengthdif = length2 - length1; } //先在长链表上走“链表长度差”步 for (int i = 0; i < lengthdif; ++i) { plistlong = plistlong->next; } //同时遍历长短两条链表 while ((plistlong != NULL) && (plistshort != NULL) && (plistlong != plistshort)) { plistlong = plistlong->next; plistshort = plistshort->next; } //得到第一个公共节点//Node pfirstcommomnode = plistlong; return plistlong;}
【程序】
#define _CRT_SECURE_NO_WARNINGS 1# include <stdio.h># include <stdlib.h># include <assert.h>typedef int DataType;typedef struct Node{ DataType data; struct Node *next;}Node, *pList, *pNode;void InitLinkList(pList *pplist){ assert(pplist); *pplist = NULL;}void PushBack(pList *pplist, DataType x){ pNode cur = *pplist; pNode pnode = NULL; assert(pplist); pnode = (pNode)malloc(sizeof(Node)); if (pnode == NULL) { perror("PushBack::malloc"); exit(EXIT_FAILURE); } pnode->data = x; pnode->next = NULL; if (cur == NULL) { *pplist = pnode; } else { while (cur->next != NULL) { cur = cur->next; } cur->next = pnode; }}void Display(pList plist){ pNode cur = plist; while (cur) { printf("%d-->", cur->data); cur = cur->next; } printf("over\n");}void PrintNode(pList plist){ pNode cur = plist; printf("%d\n", cur->data);}void Destroy(pList *pplist){ pNode cur = *pplist; assert(pplist); while (cur) { pNode del = cur; cur = cur->next; free(del); } *pplist = NULL;}unsigned int GetListLength(pList phead){ unsigned int length = 0; pNode pnode = phead; while (pnode != NULL) { ++length; pnode = pnode->next; } return length;}pNode ListFirstCommomNode(pList phead1, pList phead2){ //求两条链表的长度及链表长度差步 unsigned int length1 = 0; length1 = GetListLength(phead1); unsigned int length2 = 0; length2 = GetListLength(phead2); int lengthdif = length1 - length2; pList plistlong = phead1; pList plistshort = phead2; if (length1 < length2) { plistlong = phead2; plistshort = phead1; lengthdif = length2 - length1; } //先在长链表上走“链表长度差”步 for (int i = 0; i < lengthdif; ++i) { plistlong = plistlong->next; } //同时遍历长短链表 while ((plistlong != NULL) && (plistshort != NULL) && (plistlong != plistshort)) { plistlong = plistlong->next; plistshort = plistshort->next; } //得到第一个公共节点//Node pfirstcommomnode = plistlong; return plistlong;}void test1(){ pList plist; pList plist1; pList plist2; pNode ret = NULL; InitLinkList(&plist); InitLinkList(&plist1); InitLinkList(&plist2); PushBack(&plist2, 6); PushBack(&plist2, 7); PushBack(&plist, 1); PushBack(&plist, 2); PushBack(&plist, 3); pList tmp = plist; while (tmp->next) { tmp = tmp->next; } tmp->next = plist2; Display(plist); PushBack(&plist1, 4); PushBack(&plist1, 5); pList cur = plist1; while (cur->next) { cur = cur->next; } cur->next = plist2; Display(plist1); ret = ListFirstCommomNode(plist, plist1); PrintNode(ret); Destroy(&plist);}int main(){ test1(); system("pause"); return 0;}
运行结果:
【测试】
1、功能测试
1)输入的两条链表没有公共节点;
2)第一个公共节点在链表的中间;
3)第一个公共节点在链表的头节点;
4)第一个公共节点在链表的尾节点;
2、特殊输入测试
输入的链表头节点是NULL指针
阅读全文
0 0
- 两个链表的公共第一个公共节点
- 找到两个单向链表的第一个公共节点
- 找到两个单向链表的第一个公共节点
- 找到两个单向链表的第一个公共节点
- 两个单向链表的第一个公共节点
- 两个链表的第一个公共节点
- 寻找两个相交链表的第一个公共节点
- 两个链表的第一个公共节点
- 寻找两个相交链表的第一个公共节点
- 寻找两个相交链表的第一个公共节点
- 两个链表的第一个公共节点
- 两个链表的第一个公共节点
- 找出两个链表的第一个公共节点
- (LeetCode)两个链表的第一个公共节点
- 37 - 两个链表的第一个公共节点
- 两个链表的第一个公共节点
- 剑指offer-两个链表的第一个公共节点
- 两个链表的第一个公共节点
- 题目1043:Day of Week
- Maven精品教程零散笔记(2017年8月25日18:54:33)
- dt dl dd 的英文含义
- 【深入PHP 面向对象】读书笔记(七)
- 安装g++
- 两个链表的第一个公共节点
- 开发工具修改data-XXX值,jq.data()取不到?
- mysql中的存储过程
- 复盘_8月——(第4周工作复盘)
- centos安装rzsz
- MYSQL-自动编号,主键,唯一约束与默认值
- NTP时间服务器,VPN
- Ambari安装Presto服务(无网接入)
- 国内maven仓库