01
程序文件
I、
在交叉点/src目录下分别创建main.c、Linklist.c文件
//main.c
#include <stdio.h>
#include <stdlib.h> //包括rand()、srand()、abs()等函数
#include <time.h>
#include "LinkList.h"
int main()
{
//链表ls1
List *ls1 = CreateList();
//链表ls2
List *ls2 = CreateList();
if (NULL == ls1 || NULL == ls2)
{
printf ("创建失败\n");
}
printf ("创建成功!\n");
int i;
int num;
srand((unsigned int)time(NULL));
//链表ls1长度随机指定(10,20)
int len1 = rand()%11 + 10 ;
for (i = 0; i < len1; i++)
{
//尾插
Insert_Last(ls1, rand()%10 + 1);
}
//链表ls2 = 随机的长度(1,10) + ls1后面截取的一段
int len2 = rand()%10 + 1;
for (i = 0; i < len2; i++)
{
Insert_Last(ls2, rand()%10 + 1);
}
Node *p1 = ls1->head->next;
//p1随机指向的结点范围(15,20)
for (i = 0; i < rand()%16 + 5; i++)
{
p1 = p1->next;
}
Node *p2 = ls2->head->next;
//p2先指向ls2的尾结点
while (p2->next)
{
p2 = p2->next;
}
//p1随机指向的ls1中的那个结点的地址赋给p2,即插到ls2的链尾
//以此构造交叉链
p2->next = p1->next;
Display(ls1);
Display(ls2);
//交叉点
int pos = Find_Intersection(ls1, ls2);
printf ("交叉点在链表ls1中的位置为:%d\n", pos);
Destory(ls1);
Destory(ls2);
return 0;
}
//LinkList.c
#include <stdio.h>
#include "LinkList.h"
#include <stdlib.h>
//创建链表
List *CreateList(void)
{
List *ls = (List*)malloc(sizeof(List)/sizeof(char));
if (NULL == ls)
{
return NULL;
}
ls->head = (Node*)malloc(sizeof(Node)/sizeof(char));
if (NULL == ls->head)
{
free(ls);
return NULL;
}
ls->head->next = NULL;//空链表
return ls;
}
//尾插
BOOL Insert_Last(List *ls, Data data)
{
if (NULL == ls)
{
return ERROR;
}
Node *node = (Node *)malloc(sizeof(Node)/sizeof(char));
if (NULL == node)
{
return ERROR;
}
node->data = data;
node->next = NULL;
Node *tmp = ls->head;//头结点
//作表达式时,取指针变量中存放的地址值
while (tmp->next)
{
tmp = tmp->next;
}
//tmp->next相当于int *p = &a中的p
tmp->next = node;
return TRUE;
}
//找交叉点
int Find_Intersection(List *ls1, List *ls2)
{
if (ls1 == NULL || ls2 == NULL)
{
return -1;
}
Node *p1 = ls1->head->next;
Node *p2 = ls2->head->next;
int len1 = 1;
int len2 = 1;
int count = 0;
//分别统计长度
while (p1->next != NULL)
{
len1++;
p1 = p1->next;
}
while (p2->next != NULL)
{
len2++;
p2 = p2->next;
}
p1 = ls1->head->next;
p2 = ls2->head->next;
if (len1 >= len2)
{
int num = len1 - len2;
count = num;
while (num > 0)
{
p1 = p1->next;
num--;
}
//这里直接判断p1 和 p2是否相等,因为较短链表的头结点可能就是交点
while (p1 != p2)
{
p1 = p1->next;
p2 = p2->next;
count++;
}
return count+1;
}
else
{
int num = len2 - len1;
while (num > 0)
{
p2 = p2->next;
num--;
}
//这里直接判断p1 和 p2是否相等,因为较短链表的头结点可能就是交点
while (p1 != p2)
{
p1 = p1->next;
p2 = p2->next;
count++;
}
return count;
}
}
//打印
void Display(List *ls)
{
if (NULL == ls)
{
return;
}
Node *tmp = ls->head->next;//第一个结点
while (tmp)
{
printf ("%-4d", tmp->data);
tmp = tmp->next;
}
printf("\n");
}
//销毁
void Destory(List *ls)
{
if (NULL == ls)
{
return;
}
Node *tmp = ls->head;
//取0x1000中存放的地址/取首结点的地址、或称取头结点中的地址值
while (tmp->next)
{
Node *p = tmp->next;
tmp->next = p->next;
free(p);
}
free(ls->head);
free(ls);
}
II、
在交叉点/include目录下创建Linklist.h文件
#ifndef _LINKLIST_H_
#define _LINKLIST_H_
typedef enum {TRUE, FALSE, ERROR} BOOL;
typedef int Data;
//每一个结点中应包含一个指针变量,用它来存放下一结点的地址
typedef struct _node
{
//数据域
Data data;
//指针域
struct _node *next;
}Node;
typedef struct _list
{
//头节点
Node *head;
}List;
//创建链表
List *CreateList(void);
//尾插
BOOL Insert_Last(List *ls, Data data);
//找交叉点
int Find_Intersection(List *ls1, List *ls2);
//打印
void Display(List *ls);
//销毁
void Destory(List *ls);
#endif //_LINKLIST_H
III、
在“交叉点”目录下创建Makefile文件
src1 = $(wildcard ./src/*.c)
obj1 = $(patsubst ./src/%.c, ./obj/%.o, $(src1))
target = ./bin/a.out
all:$(target)
$(target):$(obj1)
gcc $(^) -o $(@)
$(obj1):./obj/%.o:./src/%.c
gcc -c $(^) -I ./include -o $(@) -g
.PHONY:clean all
clean:
-rm -rf $(target) $(obj1)
02
测试结果
root@lj:/交叉点# ./bin/a.out
创建成功!
10 6 10 4 6 7 9 6 4 10 2 8 10 8 4 10 3 5 4
6 4 10 2 8 10 8 4 10 3 5 4
交叉点在链表ls1中的位置为:9