• C语言强化(七)链表相交问题_2 找到无环链表相交结点


    上一节聊了判断两个【无环】链表是否相交,那么如果相交,怎么找到相交结点呢?


    题目

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


    解题步骤

    1. 判断两个【无环】链表是否相交
    2. 找到两个【无环】链表的相交结点
    3. 判断链表是否带环
    4. 判断两个【有环】链表是否相交
    5. 找到两个【有环】链表的相交结点
    思路
    • 遍历的过程中记录链表的长度L1和L2(假设L1>L2)
    • 遍历找到第一个链表中的第L1 - L2节点,
    • 链表一从第L1-L2个节点开始遍历,链表二从第一个节点遍历,相当于两链表从与相交点距离相同的两个地点同时出发
    • 每次前进一步
    • 直到找到第一个相同的节点,则可以认为两个链表存在相交节点,
    • 该点即为第一个相交节点
    思路图解

    源代码
    #include <stdio.h>
    #include<stdlib.h>
    #include <iostream>
    
    
    using namespace std;
    
    /**
    2.找到两个【无环】链表的相交结点
    思路
    	遍历的过程中记录链表的长度L1和L2(假设L1>L2)
    	然后遍历找到第一个链表中的第L1 - L2节点,
    	然后链表一从第L1-L2个节点开始遍历,
    	链表二从第一个节点遍历,每次前进一步,
    	直到找到第一个相同的节点,则可以认为两个链表存在相交节点,
    	并且该点即为第一个相交节点
    */
    
    /**
    链表结构体
    */
    struct ListNode{
    	int data;
    	ListNode * nextNode;
    	ListNode(ListNode * node,int value){
    		nextNode=node;
    		data=value;
    	}
    };
    
    ListNode * L1;
    ListNode * L2;
    
    /**
    获取链表长度
    */
    int getListLength(ListNode * head){
    	int i =0;
    	if(head==NULL)
    		return 0;
    	while(head->nextNode!=NULL){
    		head=head->nextNode;
    		i++;
    	}
    	return i;
    }
    
    /**
    获取指定位置的链表结点
    */
    ListNode * getThatListNode(ListNode * head,int pos){
    	int i =0;
    	if(head==NULL)
    		return NULL;
    	while(head->nextNode!=NULL){
    		head=head->nextNode;
    		i++;
    		if(pos==i)
    			return head;
    	}
    	return NULL;
    }
    
    /**
    获取俩无环链表相交结点
    L1:较长链表
    L2:较短链表
    */
    ListNode * getNoCircleListCrossNode(ListNode * L1,ListNode * L2){
    	ListNode * L_Long;
    	ListNode * L_Short;
    	int start;
    	int length1 = getListLength(L1);
    	int length2 = getListLength(L2);
    	if(length1>=length2){
    		L_Long=L1;
    		L_Short=L2;
    		start=length1-length2;
    	}else{
    		L_Long=L2;
    		L_Short=L1;
    		start=length2-length1;
    	}
    	L_Long=getThatListNode(L_Long,start);
    	while(L_Long->nextNode!=NULL&&L_Short->nextNode!=NULL){
    		if(L_Long==L_Short)
    			return L_Long;
    		L_Long=L_Long->nextNode;
    		L_Short=L_Short->nextNode;
    	}
    
    	return NULL;
    }
    
    //测试无环相交
    void testCross(){
    
    	//相交段
    	ListNode * node = new ListNode(NULL,0);
    	node = new ListNode(node,1);
    	node = new ListNode(node,2);
    	node = new ListNode(node,3);
    	//在此处开始相交
    	L1 = new ListNode(node,11);
    	L2 = new ListNode(node,21);
    
    	//不相交段
    	L1 = new ListNode(L1,12);
    	L1 = new ListNode(L1,13);
    
    	L2 = new ListNode(L2,22);
    	L2 = new ListNode(L2,23);
    	L2 = new ListNode(L2,24);
    	L2 = new ListNode(L2,25);
    }
    
    void main()
    {
    	testCross();
    	//int length1 = getListLength(L1);
    	//cout<<length1<<endl;
    	//ListNode * node = getThatListNode(L1, 3);
    	//cout<<node->data<<endl;
    	ListNode * node = getNoCircleListCrossNode(L1,L2);
    	if(node!=NULL)
    		cout<<node->data<<endl;
    	else
    		cout<<"无相交点"<<endl;
    	system("pause");
    }

    前两篇讨论的前提都是链表是无环的,但是如果链表有环呢?下一篇,聊。

  • 相关阅读:
    二分图的最大匹配
    染色法判定二分图
    kruskal求最小生成树
    prim算法求最小生成树
    floyd
    spfa算法
    bellman_ford
    Dijkstra
    文件操作_1-18 选择题
    会话控制_2-5 编程练习
  • 原文地址:https://www.cnblogs.com/javdroider/p/5184294.html
Copyright © 2020-2023  润新知