单链表习题:判断两个单链表是否相交,若相交则找到交点
作者:互联网
先写头文件:list.h
#pragma once
typedef int ELEM_TYPE;
//有效数据节点结构体设计(头结点借用)
typedef struct Node
{
ELEM_TYPE data;//数据域 (1.头结点:不保存任何数据 2.有效数据节点:保存有效值)
struct Node *next;//指针域 (1.头结点:保存第一个元素的地址 2.有效数据节点:保存下一个有效元素的地址)
}Node, PNode;
/*
//有效数据节点结构体设计
typedef struct Node
{
union
{
int length;
ELEM_TYPE data;//数据域 存放有效值
};
struct Node *next;//指针域 存放下一个有效数据节点的地址
}Node, PNode;
//头结点结构体设计:
typedef struct Head
{
struct Node *next;//指针域 保存第一个有效数据节点的地址
}Head, *PHead;
*/
//带头结点的单链表有哪些操作函数:
//初始化函数(对于头结点进行赋初值)
void Init_list(struct Node *plist);
//购买一个新节点
struct Node *BuyNode(ELEM_TYPE val);
//头插
bool Insert_head(struct Node *plist, ELEM_TYPE val);
//尾插
bool Insert_tail(struct Node *plist, ELEM_TYPE val);
//按位置插入(pos=0 相当于头插 pos==length 相当于尾插)
bool Insert_pos(struct Node *plist, int pos, ELEM_TYPE val);
//头删
bool Del_head(struct Node *plist);
//尾删
bool Del_tail(struct Node *plist);
//按位置删(pos==0 相当于头删 pos==length-1 相当于尾删(pos==length非法))
bool Del_pos(struct Node *plist, int pos);
//按值删
bool Del_val(struct Node *plist, ELEM_TYPE val);
//获取值位置 (如果val值存在, 则返回其地址 不然返回NULL)
struct Node* Search(struct Node *plist, ELEM_TYPE val);
//判空
bool IsEmpty(struct Node *plist);
//判满 单链表不存在满这个概念
//获取单链表有效数据节点个数
int Get_length(struct Node *plist);
//清空 相当于直接调用销毁
void Clear(struct Node *plist);
//销毁1(malloc申请来的空间 全部释放掉)
void Destroy(struct Node *plist);
//销毁2
void Destroy2(struct Node *plist);
//打印
void Show(struct Node *plist);
再写cpp文件
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include "list.h"
//确定两个单链表是否相交 (用两个指针跑到两个单链表的尾结点,然后判断是否是同一个尾结点)
bool Intersect(PNode plist1, PNode plist2)
{
//assert
PNode p1 = plist1;
PNode p2 = plist2;
for(p1; p1->next!=NULL; p1=p1->next); //此时for循环结束 p1在plist1这个单链表的尾结点上
for(p2; p2->next!=NULL; p2=p2->next); //此时for循环结束 p2在plist2这个单链表的尾结点上
return p1 == p2;
}
//确定两个单链表是否相交,并且相交的话,返回第一个相交点
struct Node *Intersect_get_Node(PNode plist1, PNode plist2)
{
//assert
int len1 = Get_length(plist1);
int len2 = Get_length(plist2);
//接下来 我们需要保证 让p永远指向较长的单链表
PNode p = len1>=len2 ? plist1 : plist2;
PNode q = len1>=len2 ? plist2 : plist1;
for(int i=0; i<abs(len1-len2); i++)//abs 计算绝对值
{
p = p->next;
}
//此时,p已经将差值跑完 这个时候 只需要循环判断p和q是否是用一个节点即可
while(p != q)//这里要么p和q指向有效地址 退出循环 要么p==q==NULL 退出循环
{
p = p->next;
q = q->next;
}
return p; //return q;
}
最后在主函数中运行
int main()
{
Node head1;
Init_list(&head1);
for(int i=0; i<10; i++)
{
Insert_pos(&head1, i, i+1);
}
Node head2;
Init_list(&head2);
for(int i=0; i<20; i++)
{
Insert_pos(&head2, i, i+101);
}
Show(&head1);
Show(&head2);
bool tag1 = Intersect(&head1, &head2);
if(tag1)
{
printf("相交了\n");
}
else
{
printf("没有相交\n");
}
PNode p = &head2;
for(int i=0; i<12; i++)
{
p = p->next;//p最后指向plist2的 112
}
PNode q = &head1;
for(int i=0; i<5; i++)
{
q= q->next;//q最后指向plist1的 5
}
p->next = q->next;//手动发生相交
Show(&head1);
Show(&head2);
//1 2 3 4 5 6 7 8 9 10
//101 102 103 104 105 106 107 108 109 110 111 112 6 7 8 9 10
tag1 = Intersect(&head1, &head2);
if(tag1)
{
printf("相交了\n");
}
else
{
printf("没有相交\n");
}
struct Node *tmp = Intersect_get_Node(&head1, &head2);
if(tmp != NULL)
{
printf("相交点的有效值为:%d\n", tmp->data);
}
bool tag2 = Del_Node((&head1)->next);
if(tag2)
{
Show(&head1);
}
return 0;
}
标签:Node,单链,struct,int,相交,next,PNode,习题,plist 来源: https://blog.csdn.net/weixin_58368590/article/details/123212139