单链表-两非递减表合并成一非递增

两非递减表合并成一非递增

将两个非递减有序链表合成一个非递增有序链表
条件:不能使用额外空间

  1. 算法思想
    利用“摘"结点的方法,每次选择结点值较小的结点插入
    比有一个链表为全合并完成,则将其结点依次以头插的形式插入表中
  2. 实现代码
LNode *MergeUpperToLower(LNode *L1,LNode *L2){
	if(L1==0||L2==0)
		return 0;

	LNode *p=L1->next,*q=L2->next,*r=L1,*temp;
	L1->next=0,L2->next=0; 
	
	while(p&&q){
		if(p->data<q->data)
			{
				temp=p;
				p=p->next;
				temp->next=L1->next;
				L1->next=temp;
			}
		else{
				temp=q;
				q=q->next;
				temp->next=L1->next;
				L1->next=temp;
		}
	} 
	while(p){
			temp=p;
			p=p->next;
			temp->next=L1->next;
			L1->next=temp;
		}
	while(q)
		{
			temp=q;
			q=q->next;
			temp->next=L1->next;
			L1->next=temp;	
		}
		p=L1->next;
		
		free(L2);
		return (LNode*)L1;
	}
	int main(){
		LNode *L1=HeadCreateList(3);
		printf("\n表一合并之前的数据:\n"); 
		LNode *p=L1->next;
		while(p){
			printf("%d",p->data);
			p=p->next;
		}
		LNode *L2=HeadCreateList(4);
		printf("表二合并之前的数据:\n"); 
		p=L2->next;
		while(p){
			printf("%d  ",p->data);
			p=p->next;
		}
		L1=MergeUpperToLower(L1,L2);
		printf("\n两表合并之后的数据:\n") ;
		p=L1->next;
		while(p){
			printf("%d",p->data);
			p=p->next;
		}
	} 

  • 完整代码
#include<stdio.h> 
#include<stdlib.h>
typedef struct LNode{
	struct LNode *next;
	int data;
}LNode;
LNode *HeadCreateList(int len)
{
	LNode *L = (LNode*)malloc(sizeof(LNode)); //创建一个头结点
	LNode *temp = L;//声明一个中间变量,指向头结点,用于遍历链表
	temp->next = NULL;	//该链表此刻只带头结点
	printf("\n请输入创建数据:\n");
	
	for(int i=1;i<=len;i++) //循环申请len个结点来接收scanf得到的元素
	{
		LNode *p = (LNode*)malloc(sizeof(LNode)); 
		p->next=0;//生成新结点
		scanf("%d",&p->data);  //用新申请的结点来接收scanf得到的元素
		/* 以下两条语句是头插法的关键步骤,与本工程"Insert"函数原理一样 */
		temp->next=p;
		temp=p;
	}
	printf("\n创建结束\n");
	return (LNode*)L;
}
//将两个非递减有序链表合成一个非递增有序链表
//条件:不能使用额外空间 
//算法思想: 
//利用“摘"结点的方法,每次选择结点值较小的结点插入  
//若有一个链表为全合并完成,则将其结点依次以头插的形式插入表中 
LNode *MergeUpperToLower(LNode *L1,LNode *L2){
	if(L1==0||L2==0)
		return 0;

	LNode *p=L1->next,*q=L2->next,*r=L1,*temp;
	L1->next=0,L2->next=0; 
	
	while(p&&q){
		if(p->data<q->data)
			{
				temp=p;
				p=p->next;
				temp->next=L1->next;
				L1->next=temp;
			}
		else{
				temp=q;
				q=q->next;
				temp->next=L1->next;
				L1->next=temp;
		}
	} 
	while(p){
			temp=p;
			p=p->next;
			temp->next=L1->next;
			L1->next=temp;
		}
	while(q)
		{
			temp=q;
			q=q->next;
			temp->next=L1->next;
			L1->next=temp;	
		}
		p=L1->next;
		
		free(L2);
		return (LNode*)L1;
	}
	int main(){
		LNode *L1=HeadCreateList(3);
		printf("\n表一合并之前的数据:\n"); 
		LNode *p=L1->next;
		while(p){
			printf("%d",p->data);
			p=p->next;
		}
		LNode *L2=HeadCreateList(4);
		printf("表二合并之前的数据:\n"); 
		p=L2->next;
		while(p){
			printf("%d  ",p->data);
			p=p->next;
		}
		L1=MergeUpperToLower(L1,L2);
		printf("\n两表合并之后的数据:\n") ;
		p=L1->next;
		while(p){
			printf("%d",p->data);
			p=p->next;
		}

	} 

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值