合并两个有序链表 递归和非递归的形式

因为两个链表head1 和head2都是有序的,所以我们只需要找把较短链表的各个元素有序的插入到较长的链表之中就可以了。

之前的思路有问题,之前总是想新建个离链表把较小的放进来,这样浪费空间还浪费时间。


源代码如下:
1 node* insert_node(node *head, node *item) //head != NULL
2 {
3 node *p = head;
4 node *q = NULL; //始终指向p之前的节点
5   
6 while(p->data < item->data && p != NULL)
7 {
8 q = p;
9 p = p->next;

10 }

//其实就是item这个节点的值小于head的头的值,所以呢上面的循环没有进去

//所以p==head,改成如下的也行

if(item->data<head->data)
{
 item->next = p;
return item;
 }

加在上面的while之前。

11 if (p == head) //插入到原头节点之前
12 {
13 item->next = p;
14 return item;
15 }
16 //插入到q与p之间之间
17 q->next = item;
18 item->next = p;
19 return head;
20 }
21   
22
23 node* merge(node* head1, node* head2)
24 {   
25 node* head; //合并后的头指针
26 node *p;   
27 node *nextP; //指向p之后
28   
29 if ( head1 == NULL ) //有一个链表为空的情况,直接返回另一个链表
30 {
31 return head2;
32 }
33 else if ( head2 == NULL )
34 {
35 return head1;
36 }
37   
38 // 两个链表都不为空
39 if(length(head1) >= length(head2)) //选取较短的链表
40 { //这样进行的插入次数要少些
41 head = head1;
42 p = head2;
43 }
44 else
45 {
46 head = head2;
47 p = head1;
48 }
49   
50 while(p != NULL)
51 {
52 nextP = p->next; //保存p的下一个节点
53 head = insert_node(head, p); //把p插入到目标链表中
54 p = nextP; //指向将要插入的下一个节点
55 }
56   
57 return head;
58 }

这里insert_node()函数是有序的插入节点,注意与前面例题中的函数有区别,这里它传入的参数是node*类型。然后在merge()函数中(代码52~55行)循环把短链表中的所有节点插入到长链表中。


下面的递归也很特别,没有像以往的那样一层层返回去,因为每一次他得到了结果,当有一个表为null时候,才是到底只是返回去一次,然后就直接return head了

接下来介绍非递归方法。比如有下面两个链表:
链表1:1->3->5
链表2:2->4->6
递归方法的步骤如下:
(1)比较链表1和链表2的第一个节点数据,由于1<2,因此把结果链表头节点指向链表1中的第一个节点,即数据1所在的节点。
(2)对剩余的链表1(3->5)和链表2再调用本过程,比较得到结果链表的第二个节点,即2与3比较得到2。此时合并后的链表节点为1->2。
接下来的过程类似(2),如此递归知道两个链表的节点都被加到结果链表中。
1 node * MergeRecursive(node *head1, node *head2)
2 {
3 node *head = NULL;
4   
5 if (head1 == NULL)
6 {
7 return head2;
8 }
9 if (head2 == NUL)
10 {
11 return head1;
12 }
13   
14 if ( head1->data < head2->data )
15 {
16 head = head1 ;
17 head->next = MergeRecursive(head1->next,head2);
18 }
19 else
20 {
21 head = head2 ;
22 head->next = MergeRecursive(head1,head2->next);
23 }
24   
25 return head ;
26 }
下面是测试程序:
1 int main()
2 {
3 node *head1 = create(); //创建单链表1
4 node *head2 = create(); //创建单链表2
5 //node *head = merge(head1, head2);
6 node *head = MergeRecursive(head1, head2);
7 print(head);
8
9 return 0;

10 }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值