5 线性表的合并

应用

线性表的合并
  1. 分别获取LA表长m和LB表长n

  2. 从LB中第1个数据元素开始,循环n次执行以下操作

    从LB中查找第i
    1 ≤ i ≤ n 1 \leq i \leq n 1in
    个数据元素赋给e。

在LA中查找元素e,如果不存在,则将e插在表LA的最后。

#include<cstdio>
#include<iostream>
using namespace std;
typedef int ElemType;

//单链表的存储结构
typedef struct LNode{
	ElemType data;  //结点的数据域
	struct LNode *next;  //结点的指针域
}LNode,*LinkList;  //LinkList为指向结构体LNode的指针类型

LNode *p;
int j;
//单链表基本操作的实现
//1 初始化
void initList(LinkList &L){
	//构造一个空的单链表
	L=new LNode;  //生成新结点作为头结点,用头指针L指向头结点
	L->next=NULL; //头结点的指针域置空
}
//2 取值 用e返回L中第i个数据元素的值
void GetElem(LinkList L,int i,ElemType &e){
	p=L->next;j=1; //初始化,P指向首元结点 
	while(p&&j<i){ //直到p为空或p指向第i个元素
		p=p->next;
		++j;
	}
	if(!p||j>i){
		perror("ERROR");
	}
	e=p->data;
}
//3 查找 在带头结点单链表L中查找值为e的元素
LNode *LocateElem(LinkList L,ElemType e){
	p=L->next;  //初始化,p指向首元结点
	while(p && p->data!=e){
		p=p->next;
	}
	return p;  //查找成功返回值为e的结点地址p,查找失败p为NULL
}
//4 插入 将值为e的新结点插入到表的第i个结点的位置上
void ListInsert(LinkList &L,int i,ElemType e){
	p=L;j=0;
	while(p && (j<i-1)){
		p=p->next;
		++j;
	}
	if(!p || j>i-1){
		perror("error");
	}
	LNode *s=new LNode;  //生成新结点*s
	s->data=e; //*s赋值
	s->next=p->next;  //*s的指针域指向第i+1个结点
	p->next=s;  //将结点*p的指针域指向结点*s
}

// 顺序
void CreateList_R(LinkList &L,int n){
	initList(L); //初始化
	LNode *r=L;
	for(int i=0;i<n;i++){
		p=new LNode;  //生成新结点
		cin>>p->data;
		p->next=NULL;
		r->next=p;
		r=p;
	}
	
}
// 遍历链表
void showList(LinkList L){
	p=L->next;
	while(p){
		cout<<p->data<<" ";
		p=p->next;
	}
}
// 链表长度
int ListLength(LinkList List){
	int len=0;
	p=List->next;
	while(p){
		len++;
		p=p->next;
	}
	return len;
}
int main(){
	//设LA=(7,5,3,11) LB=(2,6,3)
	LinkList LA,LB;
	int lenA=4,lenB=3;
	int m,n,e;
	initList(LA);
	initList(LB);
	//尾插法 顺序
	CreateList_R(LA,lenA);
	CreateList_R(LB,lenB);
	m=ListLength(LA);
	n=ListLength(LB); //求线性表的长度
	for(int i=0;i<=n;i++){
		GetElem(LB,i,e); //取LB中第i个数据元素赋值给e;
		if(!LocateElem(LA,e)){  //LA中不存在和e相同的元素
			ListInsert(LA,++m,e); //将e插在LA的最后
		}
	}
	showList(LA);  //输出合并后的LA
	return 0;
}
有序表的合并

数据元素在线性表中依值非递减或非递增有序排列,则称该线性表为有序表。

已知两个有序集合A和B,数据元素按值非递减有序排列,现要求一个新的集合C=AUB,使集合C中的数据元素仍按值非递减有序排列。

  1. 顺序表
#include<cstdio>
#define MAXSIZE 100  //顺序表可能达到的实际长度
typedef int ElemType; //定义ElemType为int类型
typedef struct{
	ElemType *elem;//存储空间的基地址
	int length;  //当前长度
}SqList;

//构造空的顺序表
void InitList(SqList &L){
	L.elem=new ElemType[MAXSIZE];
	if(!L.elem)
		perror("error");
	L.length=0;
}
void ShowList(SqList LC){
	for(int i=0;i<LC.length;i++){
		printf("%d ",LC.elem[i]);
	}
}

void MergeList_Sq(SqList LA,SqList LB,SqList &LC){
	LC.length=LA.length+LB.length;  //合并的LC的表的长度
	LC.elem=new ElemType[LC.length];
	ElemType *pc=LC.elem;  //指针pc指向新表的第一个元素
	ElemType *pa=LA.elem; ElemType *pb=LB.elem; //指针pa pb分别指向待合并表的第一个元素
	ElemType *pa_last=LA.elem+LA.length-1; //指向LA的最后一个元素
	ElemType *pb_last=LB.elem+LB.length-1; //指向LB的最后一个元素
	while((pa<=pa_last) && (pb<=pb_last)){  //LA和LB均未到达表尾
		if(*pa<=*pb)
			*pc++=*pa++;  //依次取小的值
		else
			*pc++=*pb++;
	}
	while(pa<=pa_last)
		*pc++=*pa++;  //LB已到达表尾,将LA元素剩余的插入
	while(pb<=pb_last) 
		*pc++=*pb++;  //LA到达表尾  将LB元素剩余的插入
 }



int main(){
	SqList LA,LB,LC;
	InitList(LA);
	InitList(LB);
	//假设A为3 5 8 11  B为 2 6 8 9 11 15 20
	LA.length=4;
	LB.length=7;
	for(int i=0;i<LA.length;i++){
		int item;
		scanf("%d",&item);
		LA.elem[i]=item;
	}
	for(int i=0;i<LB.length;i++){
		int item;
		scanf("%d",&item);
		LB.elem[i]=item;
	}
	MergeList_Sq(LA,LB,LC);   //合并
	ShowList(LC);   //合并后的结果   时间复杂度为O(m+n)
	return 0;
}
  1. 链表
#include<cstdio>
#include<iostream>
using namespace std;
typedef int ElemType;

//单链表的存储结构
typedef struct LNode{
	ElemType data;  //结点的数据域
	struct LNode *next;  //结点的指针域
}LNode,*LinkList;  //LinkList为指向结构体LNode的指针类型

LNode *p;
int j;
//单链表基本操作的实现
//1 初始化
void initList(LinkList &L){
	//构造一个空的单链表
	L=new LNode;  //生成新结点作为头结点,用头指针L指向头结点
	L->next=NULL; //头结点的指针域置空
}

//创建单链表  后插法 插入的元素是从前往后的
void CreateList_R(LinkList &L,int n){
	initList(L); //初始化
	LNode *r=L;
	for(int i=0;i<n;i++){
		p=new LNode;  //生成新结点
		cin>>p->data;
		p->next=NULL;
		r->next=p;
		r=p;
	}	
}
// 遍历链表
void showList(LinkList L){
	p=L->next;
	while(p){
		cout<<p->data<<" ";
		p=p->next;
	}
}
void MergeList_L(LinkList &LA,LinkList &LB,LinkList &LC){
	LNode *pa=LA->next;
	LNode *pb=LB->next;  //pa和pb的初值分别指向两个链表的第一个结点
	LC=LA;  //用LA的头结点作为LC的头结点
	LNode *pc=LC; //pc的初值指向LC的头结点
	while(pa&&pb){
		//LA 和 LB均未到达表尾
		if(pa->data<=pb->data){
			pc->next=pa;
			pc=pa;
			pa=pa->next;
		}else{
			pc->next=pb;
			pc=pb;
			pb=pb->next;
		}
	}
	pc->next=pa?pa:pb; //将非空表的剩余段插入到pc
	delete LB;  //释放LB的头结点  空间复杂度为O(1)
}
int main(){
	LNode *LA,*LB,*LC;
	initList(LA);initList(LB);
	//假设A为3 5 8 11  B为 2 6 8 9 11 15 20
	int len_la=4,len_lb=7;
	CreateList_R(LA,len_la);
	CreateList_R(LB,len_lb);
	MergeList_L(LA,LB,LC);
	showList(LC);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xuhuimingc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值