针对于上面这个问题,如果是两张单链表合并该怎么做
话不多说,直接上代码
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)