面试题—数据结构之单链表详述(基本篇4)---有序单链表的合并

本文详细讲解如何合并两个有序的单链表,包括非递归和递归两种方法。非递归方法通过将较短链表的元素有序插入到较长链表中实现。递归方法则是通过比较链表首节点,逐次合并剩余部分,直至所有节点合并完成。提供了具体的程序代码示例。
摘要由CSDN通过智能技术生成

          有序单链表的合并。已知两个链表head1和head2各自有序,请把它们合并成一个链表并且依然有序,分别使用非递归方法以及递归方法。

解析:

       首先介绍非递归方法。因为两个链表head1和head2都是有序的,所以只需要把较短链表的各个元素有序插入到较长链表之中就可以了。

程序代码:

//正向插入节点
node *insert_node(node *head, node *item)
{
	node *p = head;
	node *q = NULL;    //指向p之前的节点
	
	while(p->data < item->data && p != NULL)
	{
		q = p;
		p = p->next;
	}
	if(p == head)		//插入到原头节点之前
	{
		item->next = p;
		return head;
	}
	//插入到q与p之间
	q->next = item;
	item->next = p;

	return head;
}
int length(node *head)
{
	int len = 0;
	node *p = head;
	while(NULL != p)
	{
		len++;
		p = p->next;
	}
	return len;
}
//两个有序链表进行合并
node *my_merge(node *head1, node *head2)
{
	node *head = NULL;      //指向合并后的链表
	node *p = NULL;
	node *nextP = NULL;		//指向p之后

	if(NULL == head1)		//有一个链表为空,直接返回另一个链表
	{
		return head2;
	}
	if(NULL == head2)
	{
		return head1;
	}
	//两个链表都不为空
	if(length(head1) > length(head2))	//选取较短的链表
	{									//这样进行的插入次数要少
		head = head1;
		p = head2;
	}
	else
	{
		head = head2;
		p = head1;
	}

	while(NULL != p)
	{
		nextP = p->next;			//保存p的下一个节点
		head = insert_node(head, p);//把p插入到目标链表中
		p = nextP;					//指向将要插入的下一个节点
	}

	return head;
}
这里insert_node()函数是有序节点的插入,注意与前面文章中的函数区别,这里它传入的参数是node* 类型。然后再my_merge()函数中循环把短链表中的所有节点插入到长链表中。

接下来介绍递归方法。假设有下面两个链表。

链表1:1 -> 3 -> 5

链表2:2 -> 4 -> 6

递归方法步骤如下:

      (1)比较链表1和链表2的第1个节点数据,由于 1 < 2, 因此把结果链表头节点指向链表1中的第1个节点,即数据1所在的节点。

      (2)对剩余的链表1(3->5)和链表2再调用(1)的方法,比较得到结果链表的第2个节点,即2与3比较得到2,此时合并后的链表节点为1->2。如此递归直到连个链表的节点都被加到结果链表中,程序代码如下:

//递归方法合并两个有序链表
node *MergeRecursive(node *head1, node *head2)
{
	node *head = NULL;
	if(NULL == head1)
	{
		return head2;
	}
	if(NULL == head2)
	{
		return head1;
	}

	if(head1->data < head2->data)
	{
		head = head1;          //指向head1
		head->next = MergeRecursive(head1->next, head2);
	}
	else
	{
		head = head2;
		head->next = MergeRecursive(head1, head2->next);
	}

	return head;
}

下面是测试程序:

void print(node *head)
{
	node *p = NULL;
	int index = 0;
	if(NULL == head->next)
	{
		printf("Link is empty!\n");
		return ;
	}
	p = head->next;
	while(NULL != p)
	{
		printf("the %dth node %d\n", ++index, p->data);
		p = p->next;
	}
}
int main()
{
	node *head1 = create();
	node *head2 = create();

	//node *head = my_merge(head1, head2);

	head1 = head1->next;	//因为先要两链表其中的一个头给head
	node *head = MergeRecursive(head1, head2);

	print(head);

	return 0;
}





  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值