版权声明:本文为博主原创文章,未经博主允许不得转载,如果有错误,欢迎指正,提前感谢。 https://blog.csdn.net/Quinlan_/article/details/86748529
https://www.bilibili.com/video/av39115738
强烈安利灯笼大神的视频...上面是视频链接…下面截图是灯笼大神视频里的…
今天学了下 怎么找交叉链表会和到一起的那个结点,做个学习笔记…
#—
因为不确定list1 和 list2两条链表在汇聚到某个结点之前 ,他们各自的结点数是相同的,所以要求出这个结点数的差值。长的链表的结点数 - 短的链表的结点数 == 指向长的链表的指针需要移动的结点数
如上图p1指针指向 “1”结点,p2指针指向“7”结点,通过一个求链表中结点个数的函数得到 list1的长度为6,list2结点的个数为4。6-4=2 ,这时候将p1指针向后移动2个结点。
这时候p1和p2 同步进行移动即可到达汇集的那个结点…
#include<stdio.h>
#include<stdlib.h>
//创建一个链表结点的结构体 没有什么问题
typedef struct {
int value;
struct Node *next;
} Node;
//这个函数是用来返回链表长度的 没有什么问题
int get_list_length(Node *list)
{
Node *p = list;
int length = 0;
while( p != NULL )
{
++length;
p = (struct Node *)(p->next);
}
return length;
}
//移动结点用的,先看下面一个函数再看这个
Node *relocate_first_node(Node *list, int offset)
{
//list是要移动的那个long_list offset是往后移动的单位数
Node *p = list;
for(int i=0; i<offset; i++)
{
p = p->next;
}
// 移动好了.. 返回的 这个p指向的位置 呢,就是那个刚刚好的位置
return p;
}
//这个函数用来找相同结点用的
Node *find_common_node(Node *list1, Node *list2)
{
//先求出两条链表的长度
int length1 = get_list_length(list1);
int length2 = get_list_length(list2);
//先假设list1比list2长
Node *long_list = list1;
Node *short_list = list2;
//恰恰相反.jpg...
if( length1 < length2 )
{
long_list = list2;
short_list = list1;
}
//这时候long_list指向的就是长的那条链表
//short_list指向的就是短的那条链表
//然后求一下他们差的绝对值
int offset = abs(length1 - length2);
//p1是指向长链首结点的指针,把p1往后移动offset个单位的结点
//relocate_first_node()这个函数返回一个指针 p
//p1 = p 这时候p1的位置就是移动好以后的位置
Node *p1 = relocate_first_node(long_list, offset);
//p2的位置是首结点的位置没什么问题,因为他短
Node *p2 = short_list;
//这时候就可以开始一起移动了
while( p1 != NULL )
{
//当这俩指针指向同一个结点的时候
if( p1 == p2 )
{
// return p1 或者p2都行
return p1;
}
//p1 p2同步往后走
//这个地方用gcc编译也出现了需要强制类型转换的地方
//不是很懂为什么 网上没有搜到结果。。用-w给忽略了
p1 = p1->next;
p2 = p2->next;
}
// 如果是陌路人就返回NULL
return NULL;
}
int main()
{
//这里是构建一个上面那张图形状的交叉链表
//虽然麻烦 但重要的还是学求结点的思想..ummm
Node n1, n2, n3, n4, n5, n6, n7;
n1.value = 1;
n2.value = 2;
n3.value = 3;
n4.value = 4;
n5.value = 5;
n6.value = 6;
n7.value = 7;
// 这个地方灯笼大神视频里是没有(struct Node *)这个强制类型-
//-转换的但我的编译器会给出
//warning: assignment from incompatible pointer type
//这个问题...所以就强制类型转换了一下...
//后来在用gcc编译的时候 只需要加上-w 就可以忽略warning了...
n1.next = (struct Node *)&n2;
n2.next = (struct Node *)&n3;
n3.next = (struct Node *)&n4;
n4.next = (struct Node *)&n5;
n5.next = (struct Node *)&n6;
n6.next = NULL;
n7.next = (struct Node *)&n4;
//list1 的第一个结点是n1 list2的第一个结点是n7
Node *list1 = &n1;
Node *list2 = &n7;
//这里验证一下这个函数是不是能用....
printf("list1: %d\nlist2: %d\n",get_list_length(list1),
get_list_length(list2));
// find_common_node()返回的是指向结点的指针
Node *common = find_common_node(list1, list2);
//这时候输出值..看一下结果...就是酱
printf("common node = %d\n", common->value);
return 0;
}