有序链表和并的递归写法和非递归写法(c语言)

这篇博客介绍了如何将两个有序递增链表pa和pb合并为一个链表。分别提供了非递归和递归两种实现方法。非递归方法通过两个指针head和p进行操作,根据节点值判断将相应节点插入合并链表。递归方法则设定递归终止条件和递归过程,根据节点值决定合并方向。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

有两个有序递增链表pa和pb,现在要把他们合并成一个链表,分别用递归算法和非递归算法实现


题目分析

非递归实现:

使用两个指针head 和p ,head 作为头结点,p作为活动指针.

如果pa所指元素<pb所指元素,那么把pa所指元素,放入合并后的链表中,然后把p->next指向pa,把p指向pa,把pb向后移动,即pb=pb->next

如果pa所指元素>pb所指元素,那么把pb所指元素,放入合并后的链表中,然后把p->next指向pb,把p指向pb,把pb向后移动,即pb=pb->next

如此往复,直到pa 或者pb 为 null 为止 

核心方法如下:

//非递归实现两个链表合并 
linklist mergelist(lnode * pa,lnode*pb)
{
    int e,n;
    linklist pc,head;  
    head=pc=(linklist)malloc(sizeof(lnode));
    pc->next=NULL;
    while(pa&&pb)
    {
        if(pa->data<=pb->data) 
        {
            pc->next=pa;
            pc=pa;
            pa=pa->next;
        }
        else
        {
            pc->next=pb;
            pc=pb;
            pb=pb->next;
        }
    }
    //pc->next=pa?pa:pb;
    pa==NULL ? pc->next=pb:pc->next=pa; 
    return head; 
}



递归实现

递归终止条件:若head1为空,返回head2指针(head);若head2为空,返回head1指针(head)

递归过程:

       (1)若pa->data < pb->data;  head 指针应该指向pa所指向的节点,而且head->next应该指向pa->next和pb两个链表的合成序列的头指针;

       (2)否则head 指针应该指向pb所指向的节点,而且head->next应该指向pb和pb->next两个链表的合成序列的头指针;


核心代码如下:

/*递归的合并两个有序链表*/
lnode * mergeLinkedList(lnode * head1,lnode * head2)   
{   
   lnode *p=NULL;   
   if(head1==NULL&&head2==NULL)   
       return p;   
   else if(head1==NULL)   
       return head2;   
   else if(head2==NULL)   
       return head1;   
   else  
   {   
       if(head1->data < head2->data)   
       {   
           p = head1;   
           p->next = mergeLinkedList(head1->next,head2);   
       }   
       else  
   	   {
          p = head2;   
  		  p->next = mergeLinkedList(head1,head2->next);   
   	   }   
       return p;   
   }   
} 


完整代码


#include <stdio.h>
#include <malloc.h>

typedef struct lnode {
    
    int data;
    struct lnode *next;
}lnode,*linklist;

linklist creatlist(int m)//创建链表
{
    
    linklist p,l,s;
    int i;
    p=l=(linklist)malloc(sizeof(lnode));
    p->next=NULL;
    printf("请输入链表中的一个数字:");
    scanf("%d",&p->data);
    for(i=2;i<=m;i++)
    {
        s=(linklist)malloc(sizeof(lnode));
        s->next = NULL;
        printf("请输入第%d个数字",i);
        scanf("%d",&s->data);
        p->next=s;
        p=p->next;
    }
    printf("/n");
    return l;    
}

void print(linklist h,int type)//打印链表
{
    if(type==1){
    	linklist p=h->next;
    }else{
  		linklist p=h;
	} 
	
    int t=1;
    printf("打印各个数字:\n");
    do
    { 
        printf("请输出第%d个数:",t);
        printf("%d\n",p->data);
        p=p->next;
        t++;
    }while(p); 
}
//非递归实现两个链表合并 
linklist mergelist(lnode * pa,lnode*pb)
{
    int e,n;
    linklist pc,head;  
    head=pc=(linklist)malloc(sizeof(lnode));
    pc->next=NULL;
    while(pa&&pb)
    {
        if(pa->data<=pb->data) 
        {
            pc->next=pa;
            pc=pa;
            pa=pa->next;
        }
        else
        {
            pc->next=pb;
            pc=pb;
            pb=pb->next;
        }
    }
    //pc->next=pa?pa:pb;
    pa==NULL ? pc->next=pb:pc->next=pa; 
    return head; 
}


/*递归的合并两个有序链表*/
lnode * mergeLinkedList(lnode * head1,lnode * head2)   
{   
   lnode *p=NULL;   
   if(head1==NULL&&head2==NULL)   
       return p;   
   else if(head1==NULL)   
       return head2;   
   else if(head2==NULL)   
       return head1;   
   else  
   {   
       if(head1->data < head2->data)   
       {   
           p = head1;   
           p->next = mergeLinkedList(head1->next,head2);   
       }   
       else  
   	   {
          p = head2;   
  		  p->next = mergeLinkedList(head1,head2->next);   
   	   }   
       return p;   
   }   
} 


int main()
{
    linklist head;
    int e,n;
    lnode *pa,*pb;
    printf("请输入第一个链表的长度:");
    scanf("%d",&e);
    pa=creatlist(e);
    printf("请输入第二个链表的长度:");
    scanf("%d",&n); 
    pb=creatlist(n);
   
    //递归和非递归方法请分别执行 
   //非递归写法 
    head=mergelist(pa,pb); 
    print(head,1);
    printf("-----非递归算法结束----\n");
    
   //递归写法    
   // head=mergeLinkedList(pa,pb); 
   // print(head,2);
   // printf("----递归算法结束----\n");
    
    return 0; 
}



        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值