两个链表的合并

本文详细介绍了链表的创建、插入、遍历过程,并实现了排序算法,展示了链表在数据结构中的应用。
#include <stdio.h>
#include <malloc.h>
#define LEN sizeof(struct student)
struct  student
{long num;
 int score;
 struct student *next;
};

struct student lista,listb;
int n,sum=0;

int main()
{struct student *creat(void);
 struct student *insert(struct student  *,struct student *);
 void print(struct student *);
 struct student *ahead,*bhead,*abh;
 printf("input list a:\n");
 ahead=creat();
 sum=sum+n;
 printf("input list b:\n");
 bhead=creat();
 sum=sum+n;
 abh=insert(ahead,bhead);
 print(abh);
 return 0;
}

struct student *creat(void)       //建立链表函数
 {struct student *p1,*p2,*head;
  n=0;
  p1=p2=(struct student *)malloc(LEN);
  printf("input number & scores of student:\n");
  printf("if number is 0,stop inputing.\n");
  scanf("%ld,%d",&p1->num,&p1->score);
  head=NULL;
  while(p1->num !=0)
    {n=n+1;
     if (n==1)
       head=p1;
     else
       p2->next=p1;
     p2=p1;
     p1=(struct student *)malloc(LEN);
     scanf("%ld,%d",&p1->num,&p1->score);
    }
    p2->next=NULL;
  return(head);
}

/*struct student *creat(void)
 {
 	struct student*p1,*p2,*head;
 	n=0;
 	p1=p2=(struct student*)malloc(LEN);
 	scanf("%ld,%d",&p1->num,&p1->score);
 	while(p1->num!=0)

 	 {
	 	n=n+1;
	 	if(n==1)
	 	head=p1;
	 	else
	 	p2->next=p1;
	 	p2=p1;
 	    p1=(struct student*)malloc (LEN);
        scanf("%ld %d",&p1->num,&p1->score);
 	 }
	 p2->next=NULL;	
	 	
	 return (head);
 }
 */   
/*struct student *insert(struct student *ah,struct student *bh)   //插入函数
 {struct student * pa1,* pa2,* pb1,* pb2;
  pa2=pa1=ah;
  pb2=pb1=bh;
  do
  {while((pb1->num>pa1->num) && (pa1->next !=NULL))
           {pa2=pa1;
             pa1=pa1->next;
           }
         if (pb1->num <= pa1->num)
            {if (ah==pa1)
	             ah=pb1;
         else 
		     pa2->next=pb1;
	         pb1=pb1->next;
             pb2->next=pa1;
             pa2=pb2;
	         pb2=pb1;
	        }
	}while ((pa1->next!=NULL) || (pa1==NULL && pb1!=NULL));
    if ((pb1!=NULL) && (pb1->num>pa1->num) && (pa1->next==NULL))
      pa1->next=pb1;
    return(ah);
 }
*/
/*struct student *creat(void)
 {
 	struct student*p1,*p2,*head;
 	int n=0;
 	p1=p2=(struct student*)malloc(LEN);
 	scanf("%d,%f",&p1->num,&p1->score);
 	while(p1->num!=0)

 	 {
	 	n=n+1;
	 	if(n==1)
	 	head=p1;
	 	else
	 	p2->next=p1;
	 	p2=p1;
 	    p1=(struct student*)malloc (LEN);
        scanf("%d %f",&p1->num,&p1->score);//给成员赋值时注意要带赋值号 
 	 }
	 p2->next=NULL;	
     return (head);
 }
 
 */
 struct student *insert(struct student *ah,struct student *bh) 
 {
 	struct student *pa1,*pa2,*pb1,*pb2;
 	pa2=pa1=ah;
    pb2=pb1=bh; 
 	do
 	{
	 	while((pb1->num>pa1->num)&&(pa1->next!=NULL))
	 	{
	 		pa2=pa1;
	 		pa1=pa1->next; 
	 	}
	 	if(pb1->num<=pa1->num)
	 	   {//if(pa1=ah)
	        if(ah==pa1)//等号啊,你是让我怎么办才能不把==写成= 
	 	    	ah=pb1;
 	        else
 	        	pa2->next=pb1;
 	        	pb1=pb1->next;
 	        	pb2->next=pa1;
       		    pa2=pb2;//这个条件也容易忘记 
 	        	pb2=pb1;
	 	   }

	 }while((pa1->next!=NULL)||(pa1==NULL&&pb1!=NULL));//逗号不能忘了 ,还有==和=区分开 
	 if ((pb1!=NULL) && (pb1->num>pa1->num) && (pa1->next==NULL))
	 pa1->next=pb1;
	 return(ah);
 }
 
void print(struct student *head)  //输出函数
  {struct student  *p;
   printf("There are %d records:  \n",sum);
   p=head;
   if (p !=NULL)
     do
       {printf("%ld %d\n",p->num,p->score);
	    p=p->next;
       }while (p !=NULL);
   }

/*
1001 ,60 
1090 ,68
1050 ,58
0
1058 ,96
1040 ,52
0
*/

### 合并两个有序链表并按升序排列 在 C# 中,可以通过递归或迭代的方式实现两个有序链表合并,确保合并后的链表仍保持升序排列。以下是两种实现方式的详细说明。 #### 递归方法 递归方法通过比较两个链表的当前节点值,选择较小的节点作为当前合并后的链表的下一个节点,并递归处理剩余部分: ```csharp public class Solution { public ListNode MergeTwoLists(ListNode l1, ListNode l2) { if (l1 == null) { return l2; } else if (l2 == null) { return l1; } else if (l1.val < l2.val) { l1.next = MergeTwoLists(l1.next, l2); return l1; } else { l2.next = MergeTwoLists(l1, l2.next); return l2; } } } ``` 此方法在每次递归调用中将较小值的节点连接到结果链表中,直到其中一个链表为空为止。此实现方式简洁,但需要注意递归深度可能导致栈溢出的问题 [^2]。 #### 迭代方法 迭代方法通过循环处理两个链表,比较当前节点值并逐步构建结果链表: ```csharp public class Solution { public ListNode MergeTwoLists(ListNode l1, ListNode l2) { ListNode prehead = new ListNode(-1); ListNode prev = prehead; while (l1 != null && l2 != null) { if (l1.val <= l2.val) { prev.next = l1; l1 = l1.next; } else { prev.next = l2; l2 = l2.next; } prev = prev.next; } // 合并后 l1 和 l2 最多只有一个还未被合并完 // 直接将链表末尾指向未合并完的链表即可 prev.next = l1 == null ? l2 : l1; return prehead.next; } } ``` 此方法使用一个虚拟头节点 `prehead` 来简化链表合并的逻辑,同时通过循环逐个比较两个链表的节点值,确保结果链表始终按升序排列 。 ### 相关应用场景 - **合并多个有序链表**:可以使用分治策略,将多个链表两两合并,直到最终得到一个完整的升序链表- **动态数据结构**:链表的灵活性使其适合处理动态数据流,例如实时排序和插入操作。 ### 性能分析 递归方法的空间复杂度为 $O(n)$,主要由递归调用栈决定;迭代方法的空间复杂度为 $O(1)$,仅使用额外的指针变量。两者的时间复杂度均为 $O(n)$,其中 $n$ 是两个链表的总长度。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值