C语言强化(七)链表相交问题_1 判断无环链表相交

2023-11-10 10:10

本文主要是介绍C语言强化(七)链表相交问题_1 判断无环链表相交,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

从此篇博文开始,讲解一道古老的链表相交问题,共五篇


题目

给出俩个单向链表的头指针,比如 h1,h2,判断这俩个链表是否相交


解题步骤

  1. 判断两个【无环】链表是否相交
  2. 找到两个【无环】链表的相交结点
  3. 判断链表是否带环
  4. 判断两个【有环】链表是否相交
  5. 找到两个【有环】链表的相交结点
此篇先从最简单的判断两个【无环】链表是否相交开始,顺便介绍一下链表的基础知识,方便一些对链表不太了解的同学学习。

基础知识

什么是链表?
链表是一种物理存储单元上非连续、非顺序的存储结构数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。
——From BaiKe
画个图展示一下链表

数据结构如下
struct ListNode{int data;ListNode * nextNode;ListNode(ListNode * node,int value){nextNode=node;data=value;}
};

有环链表?
只需修改一下指针的指向,就会发现,这个链表永远不会走到尽头,如下


如何判断两个链表是否相交?
思路:只要有一个节点相同,那么两链表就相交
方法一: 遍历遍历
遍历链表一,每次遍历到链表一的一个节点时判断是否和链表二的节点相同(方法同样是遍历),有相同的则说明两链表相交。
此方法当然可行,可是时间复杂度=O(length1*length2)

方法二:哈希表法 

既然连个链表一旦相交,相交节点一定有相同的内存地址,而不同的节点内存地址一定是不同的,那么不妨利用内存地址建立哈希表,如此通过判断两个链表中是否存在内存地址相同的节点判断两个链表是否相交。具体做法是:遍历第一个链表,并利用地址建立哈希表,遍历第二个链表,看看地址哈希值是否和第一个表中的节点地址值有相同即可判断两个链表是否相交。
时间复杂度O(length1 + length2)
空间复杂度O(length1)  因为需要创建大小为length1的哈希表

分析:时间复杂度是线性的,可以接受,并且可以顺便找到第一个相交节点,但是却增加了O(length1)的空间复杂度,这显然不能令人满意。——ref:http://www.cnblogs.com/BeyondAnyTime/archive/2012/07/06/2580026.html


方法三:比较尾结点

只要两链表相交,那么相交后的那一段肯定是一样的,也就意味着尾结点是一样的

时间复杂度O(length1 + length2)

空间复杂度O(0)  


寻找尾结点的函数,很简单,就不解释了

/**
寻找尾结点
*/
ListNode * getLastNode(ListNode * head){if(head==NULL)return NULL;while(head->nextNode!=NULL){head=head->nextNode;}return head;
}


源代码

#include <stdio.h>
#include<stdlib.h>
#include <iostream>using namespace std;/**
1.判断两个【无环】链表是否相交
思路
判断尾节点是否相等
*//**
链表结构体
*/
struct ListNode{int data;ListNode * nextNode;ListNode(ListNode * node,int value){nextNode=node;data=value;}
};ListNode * L1;
ListNode * L2;//遍历链表
void ScanList(ListNode * node){while(NULL!=node){cout<<node->data<<endl;node = node->nextNode;}
}/**
寻找尾结点
*/
ListNode * getLastNode(ListNode * head){if(head==NULL)return NULL;while(head->nextNode!=NULL){head=head->nextNode;}return head;
}//测试无环相交
void testCross(){ListNode * node = new ListNode(NULL,0);node = new ListNode(node,1);node = new ListNode(node,2);L1 = new ListNode(node,11);L1 = new ListNode(L1,12);L1 = new ListNode(L1,13);L2 = new ListNode(node,21);L2 = new ListNode(L2,22);L2 = new ListNode(L2,23);
}//测试无环不相交
void testNotCross(){L1 = new ListNode(NULL,11);L1 = new ListNode(L1,12);L1 = new ListNode(L1,13);L2 = new ListNode(NULL,21);L2 = new ListNode(L2,22);L2 = new ListNode(L2,23);
}void main()
{testCross();//testNotCross();ListNode * node1 = getLastNode(L1);ListNode * node2 = getLastNode(L2);if(node1==node2)cout<<"相交"<<endl;elsecout<<"不相交"<<endl;system("pause");
}

既然知道两个【无环】链表相交,那么怎么找到相交结点,下一节,聊聊这个。







转载于:https://www.cnblogs.com/javdroider/p/5184295.html

这篇关于C语言强化(七)链表相交问题_1 判断无环链表相交的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/381998

相关文章

怎样通过分析GC日志来定位Java进程的内存问题

《怎样通过分析GC日志来定位Java进程的内存问题》:本文主要介绍怎样通过分析GC日志来定位Java进程的内存问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、GC 日志基础配置1. 启用详细 GC 日志2. 不同收集器的日志格式二、关键指标与分析维度1.

Java 线程安全与 volatile与单例模式问题及解决方案

《Java线程安全与volatile与单例模式问题及解决方案》文章主要讲解线程安全问题的五个成因(调度随机、变量修改、非原子操作、内存可见性、指令重排序)及解决方案,强调使用volatile关键字... 目录什么是线程安全线程安全问题的产生与解决方案线程的调度是随机的多个线程对同一个变量进行修改线程的修改操

Redis出现中文乱码的问题及解决

《Redis出现中文乱码的问题及解决》:本文主要介绍Redis出现中文乱码的问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. 问题的产生2China编程. 问题的解决redihttp://www.chinasem.cns数据进制问题的解决中文乱码问题解决总结

Go语言中nil判断的注意事项(最新推荐)

《Go语言中nil判断的注意事项(最新推荐)》本文给大家介绍Go语言中nil判断的注意事项,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1.接口变量的特殊行为2.nil的合法类型3.nil值的实用行为4.自定义类型与nil5.反射判断nil6.函数返回的

Go语言数据库编程GORM 的基本使用详解

《Go语言数据库编程GORM的基本使用详解》GORM是Go语言流行的ORM框架,封装database/sql,支持自动迁移、关联、事务等,提供CRUD、条件查询、钩子函数、日志等功能,简化数据库操作... 目录一、安装与初始化1. 安装 GORM 及数据库驱动2. 建立数据库连接二、定义模型结构体三、自动迁

全面解析MySQL索引长度限制问题与解决方案

《全面解析MySQL索引长度限制问题与解决方案》MySQL对索引长度设限是为了保持高效的数据检索性能,这个限制不是MySQL的缺陷,而是数据库设计中的权衡结果,下面我们就来看看如何解决这一问题吧... 目录引言:为什么会有索引键长度问题?一、问题根源深度解析mysql索引长度限制原理实际场景示例二、五大解决

Springboot如何正确使用AOP问题

《Springboot如何正确使用AOP问题》:本文主要介绍Springboot如何正确使用AOP问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录​一、AOP概念二、切点表达式​execution表达式案例三、AOP通知四、springboot中使用AOP导出

Python中Tensorflow无法调用GPU问题的解决方法

《Python中Tensorflow无法调用GPU问题的解决方法》文章详解如何解决TensorFlow在Windows无法识别GPU的问题,需降级至2.10版本,安装匹配CUDA11.2和cuDNN... 当用以下代码查看GPU数量时,gpuspython返回的是一个空列表,说明tensorflow没有找到

解决未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4‘问题

《解决未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4‘问题》:本文主要介绍解决未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4... 目录未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4‘打开pom.XM

C++链表的虚拟头节点实现细节及注意事项

《C++链表的虚拟头节点实现细节及注意事项》虚拟头节点是链表操作中极为实用的设计技巧,它通过在链表真实头部前添加一个特殊节点,有效简化边界条件处理,:本文主要介绍C++链表的虚拟头节点实现细节及注... 目录C++链表虚拟头节点(Dummy Head)一、虚拟头节点的本质与核心作用1. 定义2. 核心价值二