目录
问题描述:
已知有两个有序的集合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);
}