循环链表之两个循环链表合并

针对于上面这个问题,如果是两张单链表合并该怎么做 

话不多说,直接上代码

main.c

#include <stdio.h>
#include <stdlib.h>
#include <linklist.h>

void merge(link_list_node *p_head1,link_list_node *p_head2) 
{
	//用p_head1当做整张表的表头
	//先把p_head1循环到尾部
	link_list_node *p_node = p_head1;
	while(p_node -> next != NULL) {
		p_node = p_node->next;
	}
	//p_head2的头部不要,同时p_head1的链表长度会发生改变
	//确定一下p_head1的长度
	int grow_len = get_len(p_head2);
	p_head1->value = get_len(p_head1) + grow_len;
	p_node->next = p_head2->next;//直接指向了p_head2的第一个结点
}

int main()
{
	link_list_node *p_head1 = create();
	//创建两个链表
	insert_elem(p_head1,1,get_len(p_head1));
	insert_elem(p_head1,2,get_len(p_head1));
	insert_elem(p_head1,3,get_len(p_head1));
	
	link_list_node *p_head2 = create();
	insert_elem(p_head2,4,get_len(p_head2));
	insert_elem(p_head2,5,get_len(p_head2));
	insert_elem(p_head2,6,get_len(p_head2));
	
	//链表合并
	merge(p_head1,p_head2);
	print_list(p_head1);
	return 0;
}

上面还是用了自己的库,不会的去看我的linux之动态库与静态库的制作

运行结果:

然后做一个简要分析:上面两张单链表合并,其中某一张单链表就会循环到尾部,然后在从尾部链接下一个单链表的头结点 ,这个就会存在一个O(n)的时间复杂度

那么如果用循环链表是什么样子呢?或者说它的时间复杂度会是一个什么情况

这里先来说一个设计思想

话不多说,直接上代码

main1.c

#include <stdio.h>
#include <stdlib.h>
typedef int elem_type;


typedef struct _node node;
//数据结点
struct _node {
	elem_type value;
	node *next;
};

//头结点
typedef struct _t_node {
	int length;
	node *next;
}t_node;

//还是要创建一个表头
t_node *create_list()
{
	t_node *p_head = (t_node*)malloc(sizeof(t_node));
	if(p_head != NULL) {
		p_head->length = 0;
		p_head->next = NULL;//因为让让最后一个结点指向第一个结点
	}
	return p_head;
}

//数据全部直接尾插
int insert_elem(t_node *p_head,elem_type value)
{
	int res = 0;
	if(p_head != NULL) {
		node *data_node = (node*)malloc(sizeof(node));
		if(data_node != NULL) {
			node *p_node = (node*)p_head;
			int n = p_head->length;
			data_node->value = value;
			if(n == 0) {
				p_head->next = data_node;//指向第一个数据结点
				//第一个结点自己链接自己
				data_node->next = data_node;
			} else {
				int i;
				for(i = 0;i < n;i++) {
					p_node = p_node->next;
				}
				data_node->next = p_node->next;
				p_node->next = data_node;
			}
			res = p_head->length++;
		}	
	}
	return res;
}  

void print_list(t_node *p_head) 
{
	if(p_head != NULL) {
		int n = p_head->length;
		node *p_node = (node*)p_head->next;
		int i;
		for(i = 0;i < n;i++) {
			printf("%d ",p_node->value);
			p_node = p_node->next;//指针不断往下面走				
		}
	}
}

//合并两张链表
void merge_list(t_node *p_head1,t_node *p_head2) 
{
	node *p_node1 = p_head1->next;
	node *p_node2 = p_head2->next;
	if(p_node1 != NULL && p_node2 != NULL) {
		//交换两者第一个结点的next
		//这里以p_node2为头结点
		//其实就是形成了一个圆啊
		node *p_bak = p_node1->next;
		p_node1->next = p_node2->next;
		p_node2->next = p_bak;
		//两者链表的长度都要增加
		int n1 = p_head1->length;
		int n2 = p_head2->length;
		p_head1->length += n2;
		p_head2->length += n1;		
	}
}

int main()
{
	t_node *p_head1 = create_list();
	insert_elem(p_head1,1);
	insert_elem(p_head1,2);
	insert_elem(p_head1,3);
	t_node *p_head2 = create_list();
	insert_elem(p_head2,4);
	insert_elem(p_head2,5);
	insert_elem(p_head2,6);
	merge_list(p_head1,p_head2);
	print_list(p_head1);//随便 
	return 0;
}

 运行结果:

拿出核心代码看一下

 

静态链表的合并,并不需要像单链表一样把一张表的指针移动到尾部,他只需要改变尾部指针就行。所以,它需要的时间复杂度就是O(1)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值