数据结构——找两个单链表的交叉点,并将交叉点在链表ls1中所处的位置打印出来

1、程序文件
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)	

2、测试结果

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

猜你喜欢

转载自blog.csdn.net/ypjsdtd/article/details/84930499