有序表的合并(顺序有序表,链式有序表)

目录

 

问题描述:

问题分析:

1、顺序有序表:

核心代码

整体代码: 

运行结果截图:

2、链式有序表

核心代码:

整体代码:

运行结果截图:


问题描述:

已知有两个有序的集合A和B,两个集合中的数据元素都是按照非递减有序排列,现要求有一个新的集合C,且C=A∩B,并且C中的元素也要按照 非递减有序排列,例如:

A=(3,5,8,11),B=(2,6,8,9,11,15,20),则C=(2,3,5,6,8,8,9,11,11,15,20)

问题分析:

1、顺序有序表:

用两个线性表LA和LB分别表示集合A和集合B,利用两个指针pa和pb,分别指向LA和LB的第一个元素,如果pa所指的元素小于等于pb所指的元素(*pa<=*pb),则将pa所指元素存入到pc所指的存储空间中,并将pa和pc所指单元向下移动(pa++;pc++;),同理若pa所指的元素大于pb所指的元素,则pb++;pc++;

操作步骤:

1.引入指针pa、pa_last、pb、pb_last,使其分别指向LA的第一个元素,LA的最后一个元素,           LB的第一个元素,LB的最后一个元素

2.创建一个长为LA.length+LB.length的空表LC,并初始化指针pc,使其指向LC的第一个元素

3.当pa和pb均未达到相应的表尾时,循环执行以下操作

  • 如果pa所指元素值小于pb所指元素值,将pa所指元素赋值给pc,即插入LC的最后一个位置,同时pa++,pc++
  • 否则,将pb所指元素赋值给pc,即插入LC的最后一个位置,同时pb++,pc++

4.判断如果LA中仍有剩余元素,则将LA中的所有元素顺序写入LC中

5.否则,将LB中的剩余元素顺序写入LC中 

核心代码

void MergeList_Sq(SqList LA,SqList LB,SqList &LC)
{
	int *pa,*pa_last,*pb,*pb_last,*pc;
	LC.length=LA.length+LB.length;
	LC.elem=new ElemType[LC.length];
	pa=LA.elem;pa_last=LA.elem+LA.length-1;
	pb=LB.elem;pb_last=LB.elem+LB.length-1;
	pc=LC.elem;
	while((pa<=pa_last) && (pb<=pb_last)){
		if(*pa<=*pb) *pc++=*pa++;
		else  *pc++=*pb++;
	}
	while(pa<=pa_last) *pc++=*pa++;
	while(pb<=pb_last) *pc++=*pb++;
} 

整体代码: 

#include<bits/stdc++.h>
using namespace std;
#define MAXSIZE 20
#define OK 1
#define ERROR 0
typedef int ElemType;
typedef int Status;
typedef struct
{
	ElemType *elem;
	int length; 
}SqList;
 
//线性表的初始化 
Status InitList(SqList &L)
{
	L.elem=new ElemType[MAXSIZE];
	if(L.elem==NULL) return ERROR;
	L.length=0;
	return OK;
}
 
//线性表的存值
void Creat_n(SqList &L,int n)
{
	ElemType c;
	printf("请输入线性表的%d个值:\n",n);
	for(int i=0;i<n;i++){
		scanf("%d",&c);
		L.elem[i]=c;
		L.length++;
	}
} 

//打印线性表
void Display(SqList L)
{
	for(int i=0;i<L.length;i++)
		 printf("%d ",L.elem[i]);
	printf("\n");
}
 
//线性表的合并
void MergeList_Sq(SqList LA,SqList LB,SqList &LC)
{
	int *pa,*pa_last,*pb,*pb_last,*pc;
	LC.length=LA.length+LB.length;
	LC.elem=new ElemType[LC.length];
	pa=LA.elem;pa_last=LA.elem+LA.length-1;
	pb=LB.elem;pb_last=LB.elem+LB.length-1;
	pc=LC.elem;
	while((pa<=pa_last) && (pb<=pb_last)){
		if(*pa<=*pb) *pc++=*pa++;
		else  *pc++=*pb++;
	}
	while(pa<=pa_last) *pc++=*pa++;
	while(pb<=pb_last) *pc++=*pb++;
} 
 
int main()
{
	SqList LA,LB,LC;
	int p1,p2,len1,len2;
	p1=InitList(LA);p2=InitList(LB);
	if(p1==0 || p2==0) printf("初始化失败!");
	else{	
		printf("请输入LA中元素个数:");
		scanf("%d",&len1);
		Creat_n(LA,len1);
		printf("请输入LB中元素个数:");
		scanf("%d",&len2);
		Creat_n(LB,len2);
		MergeList_Sq(LA,LB,LC);
		printf("有序表合并后为:");
		Display(LC);
	}		
}

运行结果截图:

2、链式有序表

用链式方式合并两个有序表为一个有序表时,不需要再申请额外的存储空间,只需要改变指针的指向即可,引入指针pa和pb,分别指向LA和LB中等待比较的元素(如下图所示),再引入指针pc,使指针pc指向当前LC中的最后一个元素,方便下一次元素的插入。

需要注意的是新生成的结点LC的头结点只需要借用LA或者LB中的头结点即可,无需再申请新的结点,但是没有用到的头结点需要释放

算法描述:

1.初始化指针pa和pb,让其指向链表LA和LB中的首元结点(准备第一次比较)

2.LC的头结点利用LA或者LB中的头结点(这里用到的是LA中的头结点)

3.初始化指针pc,使其指向LC中的头结点

4.当pa!=NULL并且pb!=NULL时循环执行以下操作

  • 当pa所指结点的数据域小于pb所指结点的数据域时,将pc的next域指向pa,pc指向pa,pa指向下一结点
  • 否则, 将pc的next域指向pb,pc指向pb,pb指向下一结点'

5.判断LA表是否为空,若不为空,修改pc所指结点的指针域的指向,使其指向pa,将LA中的剩余元     素写入LC中 

6.判断LB表是否为空,若不为空,修改pc所指结点的指针域的指向,使其指向pb,将LB中的剩余元     素写入LC中 

7.释放LB的头结点

核心代码:

void MergeList_L(LinkList &LA,LinkList &LB,LinkList &LC)
{
	LNode *pa,*pb,*pc;
	pa=LA->next;
	pb=LB->next;
	LC=LA;
	pc=LC;
	while(pa!=NULL && pb!=NULL)
	{
		if(pa->data<pb->data){
			pc->next=pa;
			pc=pa;
			pa=pa->next;
		}
		else{
			pc->next=pb;
			pc=pb;
			pb=pb->next;
		}
	}
	if(pa!=NULL) pc->next=pa;
	else if(pb!=NULL) pc->next=pb;
	delete LB;
}

整体代码:

//链式有序表的合并
#include<bits/stdc++.h>
using namespace std;
typedef int ElemType;
typedef int Status;
#define OK 1
#define ERROR 0 


//单链表的存储结构 
typedef struct LNode{
	ElemType data;
	struct LNode *next;
}LNode,*LinkList;


//初始化单链表 
Status InitList(LinkList &L)
{
	L=new LNode;
	L->next=NULL;
	return OK;
}


//后插法创建单链表 
void CreatList_H(LinkList &L,int n)
{
	LNode *p,*r;
	L=new LNode;
	L->next=NULL;
	r=L;
	cout<<"请输入"<<n<<"个元素"<<endl; 
	for(int i=0;i<n;i++){
		p=new LNode;
		cin>>p->data;
		p->next=NULL;r->next=p;
		r=p;
	}
}

//合并单链表 
void MergeList_L(LinkList &LA,LinkList &LB,LinkList &LC)
{
	LNode *pa,*pb,*pc;
	pa=LA->next;
	pb=LB->next;
	LC=LA;
	pc=LC;
	while(pa!=NULL && pb!=NULL)
	{
		if(pa->data<pb->data){
			pc->next=pa;
			pc=pa;
			pa=pa->next;
		}
		else{
			pc->next=pb;
			pc=pb;
			pb=pb->next;
		}
	}
	if(pa!=NULL) pc->next=pa;
	else if(pb!=NULL) pc->next=pb;
	delete LB;
}

//单链表的遍历
void Display(LinkList L)
{
	LNode *p;
	p=L->next;
	cout<<"当前单链表为:"<<endl; 
	while(p!=NULL){
		cout<<p->data<<" ";
		p=p->next;
	}
	cout<<endl;
} 


int main()
{
	LinkList LA,LB,LC;
	InitList(LA);
	InitList(LB);
	int n1,n2;
	cout<<"请输入单链表A中的元素个数:";
	cin>>n1;
	CreatList_H(LA,n1);
	cout<<"请输入单链表B中的元素个数:";
	cin>>n2;
	CreatList_H(LB,n2);
	MergeList_L(LA,LB,LC);
	Display(LC);
} 

 运行结果截图:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值