实验11 problem 9 链表归并

该博客讨论了如何使用C语言解决链表归并问题。给定两个递增正整数序列A和B,目标是保持序列A的递增顺序,将序列B中的元素合并到A中,重复元素保留在B中。博主提供了输入输出示例,并说明了在归并过程中不释放B中的节点空间,而是调整指针以实现元素从B到A的移动。

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

Problem9:
链表归并问题描述:已知有两个递增的正整数序列A和B,序列中元素个数未知,同一序列中不会有重复元素出现,有可能某个序列为空。现要求将序列B归并到序列A中,且归并后序列A的数据仍然按递增顺序排列。如果序列B中某些数据在序列A中也存在,则这些数据所在节点仍然留在序列B中,而不被归并到序列A中;否则这些数据所在节点将从序列B中删除,添加到序列A中。建立两个单链表A、B用于存储两个正整数序列,然后按照题目的要求,将链表B中的元素归并到链表A中。在归并的过程中,不要释放B中的节点空间、然后建立新节点,而要改变指针的指向,使元素从B中删除并添加到A中。正整数序列按照递增顺序输入,用-1作为结束标志,注意-1不算这个正整数序列中的元素(不要统计-1)。在程序结束前要释放链表A、B中的所有节点。输入与输出要求:依次输入两个递增的正整数序列A和B,序列元素的个数未知,但以输入-1结束,每个正整数序列占一行。输出处理后的链表A中的元素,占一行;然后是处理后的链表B中的元素,占一行。每行的元素之间有一个空格,注意最后一个元素后只有换行符,如果某个链表为空,则输出“ThereisnoiteminXlist.”。

程序运行效果:
Sample1:
Please input the elements of listA:1 3 4 5 6 7 -1↙
Please input the elements of listB:2 3 6 8 9 10 11 -1↙
The new listA:1 2 3 4 5 6 7 8 9 10 11
The new listB:3 6

Sample2:
Please input the elements of listA:-1↙
Please input the elements of listB:-1↙
There is no item in Alist.
There is no item in Blist.

#include<stdio.h>
#include<stdlib.h>


typedef struct List{
	int number;
	struct List* next;
}list;
typedef list* listPtr;



listPtr print(void);   //创建链表并输入数据 

listPtr sort(listPtr);  //链表排序 



void main()
{
	listPtr A,B;
	
	
	
	//输入A、B 
	
	
	printf("listA\n");
	A=print();     
	printf("listB\n");
	B=print();
	
 if(A!=NULL&&B!=NULL)            /*在A、B都不为空的一般情况下*/
 {    
	
	
	
	//将A、B合为一个链表 
	
	
    listPtr lastA;
	for(lastA=A;lastA->next!=NULL;lastA=lastA->next);
	lastA->next=B;
	listPtr head=A;
	
	
	
	
	//对新的链表进行排序
	
	 
    head=sort(head);
    
    
    
    
    
    /*对新的链表进行如下处理:将新链表记为A链表遍历链表,若有
	某两节点中储存的数据相同,则第一个节点仍在A链表中,将第二
	个节点移动到B链表中*/
	
	 
    A=head;
    B=NULL;
    listPtr ba=head,a=head->next,b=NULL;      /*ba为a节点的前一节点
	                                           a节点为A链表中的临时
											   节点,b节点为将要存到
											   B链表中的临时节点*/ 
    while(a!=NULL)
    {
    	if(ba->number==a->number)             /*找到A链表中储存数据
		                                          相同的两节点*/ 
    	{
    		ba->next=a->next;
    		if(b==NULL)                      /*此时B链表中没有节点*/ 
    		{
    			ba->next=a->next;
    			a->next=NULL;
    		    b=a;
    		    B=b;
    		    a=ba->next;
    		}
    		else                             /*B链表中已有节点*/ 
    		{
    			ba->next=a->next;
    			a->next=NULL;
    			b->next=a;
    			b=a;
    			a=ba->next;
			}
		}
		else                                 /*循环*/ 
		{
			ba=a;
			a=a->next;
		}
	}
    
    
    
    
    
    //输出A、B链表并释放
	
	 
	printf("The new list A:");
	for(a=A;A!=NULL;A=A->next)
	    printf("%d ",A->number);

	for(b=a->next;b!=NULL;a=b,b=a->next)
	    free(a);
	    
	    
	printf("\n");
	
	
	if(B==NULL)
	    printf("There is no item in B list.");
	else
	{
		printf("The new list B:");
	    for(a=B;B!=NULL;B=B->next)
	        printf("%d ",B->number); 
    }
    for(b=a->next;b!=NULL;a=b,b=a->next)
	    free(a);
	    
 }
 else
 {
 	listPtr a,b;                              /*用于释放链表*/ 
 	if(A!=NULL)                               /*A不为空,则B必为空*/ 
 	{
 	  	printf("The new list A:");
	    for(a=A;A!=NULL;A=A->next)
	        printf("%d ",A->number);
	    for(b=a->next;b!=NULL;a=b,b=a->next)
 	        free(a);
 	    printf("\n");
 	    printf("There is no item in B list.");
    }
    else if(B!=NULL)                          /*A为空,B不为空
	                                           则B中数据均储存
											   到A中,B变为空*/ 
    {
    	A=B;
    	printf("The new list A:");
	    for(a=A;A!=NULL;A=A->next)
	        printf("%d ",A->number);
	    for(b=a->next;b!=NULL;a=b,b=a->next)
 	        free(a);
 	    printf("\n");
 	    printf("There is no item in B list.");
	}
	else                                      /*A、B均为空*/ 
	{
		printf("There is no item in A list.\n");
		printf("There is no item in B list.");
	}
	    
 	
 } 
    return 0;	 
}





//创建链表输入数据
 
listPtr print(void)
{
	listPtr head=NULL,last=NULL,current=NULL;
	int num;
	scanf("%d",&num);
	while(num!=-1)
	{
		current=(listPtr)malloc(sizeof(list));
		current->number=num;
		current->next=NULL;
		if(head==NULL)
		{
			head=current;
			last=current;
		}
		else
		{
			last->next=current;
			last=current;
		}
		scanf("%d",&num);
	}
	return head;
} 



//链表排序

 
listPtr sort(listPtr head)
{
	/*链表排序*/
	
	/*排序思路:将链表中的某一结点p,与该节点之前的节点q逐一比较大小,
	假设此时q节点中的number大于p节点中的number,则将p节点插入到q节点
	之前*/ 
	/*插入方式为:1、令p节点的前一节点bp(before p)中指针指向p节点的
	后一节点;    2、令p节点指针指向q节点;   3、令q节点的前一节点bq
	中的指针指向p节点。*/ 
	/*如此操作之后可知,循环之初的p节点为bp->next,即链表第三节点,
	q节点为bq->next,即链表第二节点, 故而比较大小是从第三节点开始每
	一节点和第二节点进行比较,而忽略了头节点,即该组数据的第一个数。
	因此:必须先找到链表中最小的节点并将该节点作为头节点,再进行上述操作*/
		 
	/*找到链表中的最小节点并作为头节点*/  
	
	listPtr min,current;
	min=(listPtr)malloc(sizeof(list));  //创建临时内存空间存储最小节点 
	min->number=head->number;
	min->next=NULL;
	
    for(current=head;current!=NULL;current=current->next)
    {
    	if(min->number>current->number)
    	{
    		min->number=current->number;
		}
	}
	min->next=head;
	head=min;                        //头节点设为链表中的最小节点 
	
	
	
	
	/*排序*/
	 
	listPtr bp=head->next,p=bp->next,bq=head,q=bq->next,newp;
	while(p)
	{
		for(bq=head,q=bq->next;q!=p;bq=q,q=q->next)
		{
			if(q->number>=p->number)  /*判断q中number大于p*/ 
			{
				newp=p;            /*复制p节点为newp*/ 
				bp->next=p->next;  /*bp指向p的下一节点*/ 
				newp->next=q;      /*newp指向q*/ 
				bq->next=newp;     /*bq指向newp*/ 
				p=p->next;         /*p更正为p的下一节点,以便循环*/ 
				break;
			}
		}
		if(q==p)                   /*此为p节点之前的所有节点均小于p*/ 
		{
			bp=p;                  /*bp更正为bp的下一节点*/ 
			p=p->next;             /*p更正为p的下一节点*/ 
		} 
	}
	p=head; 
	head=head->next;
	free(p);                       /*释放临时储存空间*/ 
	return head;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值