数据结构_线性表的归并

1,无序情况

利用两个线性表L1,L2分别表示两个集合A,B,现在要求用一个新的集合A来表示归并后的集合,也就是在A的基础上把B中与A不同的元素归并到A中,这样得到的A就是两个集合的归并。

思路:

1>B中的元素依次取出与A中的元素挨个比较,如果该元素与A中的元素均不等,则将该元素插入到线性表A的后边。

2>将B中的每一个元素都比较完且都已经按条件插入到A中,这样得到的A即时归并后的集合。

注意:线性表A申请的动态空间大小要求能承载归并后所有的元素。

遇到的问题:1>函数指针作为函数的参数这一块刚开始没有理解明白,对函数指针的概念理解不够透彻。

                      2>对于函数参数中什么时候需要引用什么时候不用理解不清晰。

以下为实验代码:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define OK 1
#define TRUE 1
#define ERROR 0
#define FALSE 0
#define OVERFLOW -2
#define INFEASIBLE -1
typedef int Status;
typedef Status ElemType;
typedef ElemType * List;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
Status InitList(List &L);
Status ListLength(List L);
Status ListInsert(List &L,ElemType i,ElemType e);
Status equal(ElemType e1,ElemType e2);
Status LocateElem(List L,ElemType e,Status (*equal)(ElemType,ElemType));
Status GetElem(List L,ElemType i,ElemType &e);
void uion(List &L1,List L2);
Status DestroyList(List &L);
int main(int argc, char *argv[]) {
	List L1;
	List L2;
	Status i=0,s,u; 
	if(InitList(L1)==0){
		printf("列表一动态内存空间申请失败;");	
	}
	List a1=L1;
	printf("请输入线性表L1待输入元素的个数:");
	scanf("%d",&s); 
	if(s>10){
		printf("输入个数超过申请空间的范围"); 
	}else{
		printf("请输入线性表1的元素:");
		for(i=0;i<s;i++){
			scanf("%d",(a1+i));
		}
	}
	printf("\n");
	
	if(InitList(L2)==0){
		printf("列表二动态内存空间申请失败;");	
	}
	List a2=L2;
	printf("请输入线性表L1待输入元素的个数:");
	scanf("%d",&u);
	if(u>10){
		printf("输入个数超过申请空间的范围"); 
	}else{
		printf("请输入线性表2的元素:");
		for(i=0;i<u;i++){
			scanf("%d",(a2+i));
		}
	} 
	printf("\n");
/********检验插入函数的功能是否实现************ 
	Status a,b;
	printf("输入待插入元的位置以及数值(试验先插入L1当中):");
	scanf("%d",&a);
	scanf("%d",&b);
	ListInsert(L1,a,b);
	printf("输出插入元素以后表L1的元素序列:");
	for(i=0;i<ListLength(L1);i++){
		printf(" %d",L1[i]);
	}
*/ 
	uion(L1,L2);
	printf("请输出归并后L1的元素序列:"); 
	for(i=0;i<ListLength(L1);i++){
		printf(" %d ",L1[i]);
	}
	printf("\n");
	 
	if(DestroyList(L1)){
			printf("线性表L1已经销毁;\n"); 
		}
	if(DestroyList(L2)){
			printf("线性表L2已经销毁;\n"); 
		}
	
	return 0;
}

Status InitList(List &L){
	L=(ElemType*)malloc(sizeof(ElemType)*12);
	if(L==NULL){
		return ERROR;
	}else{
		return OK;
	}
}

Status ListLength(List L){             //返回列表的长度 
	Status m=0;
	while(*L++){
		m++;
	}
	return m;
}

Status ListInsert(List &L,ElemType i,ElemType e){          //在L的第i个元素前插入元素e 
	ElemType j;
	for(j=ListLength(L);j>=i;--j){
		*(L+j)=*(L+j-1); 
	}
	*(L+i-1)=e;
}

Status equal(ElemType e1,ElemType e2){
	if (e1==e2){
		return 0;
	}else{
		return 2;
	}
}

Status LocateElem(List L,ElemType e,Status (*equal)(ElemType,ElemType)){        //判断L1的表中是否有与元素e相同的元素 
    Status i=1;
	while(i<=ListLength(L)&&(*equal)(L[i-1],e)){
		i++;
	}
	
	if(i<=ListLength(L)){
		return i; 
	}else{
		return 0;
	}
}

Status GetElem(List L,ElemType i,ElemType &e){           //用e返回函数中第i个元素的值 
	e=L[i-1];
	return e; 
}

void uion(List &L1,List L2){
	Status L1_length=ListLength(L1);
	Status L2_length=ListLength(L2);
	Status i,e;
	for(i=1;i<=L2_length;i++){
		GetElem(L2,i,e);                               //L2中逐个取出元素 
		if(!LocateElem(L1,e,eAqual)){                   //L2中的元素挨个与L1中的元素比较异同 
			ListInsert(L1,++L1_length,e);              //不重复则插入到L1当中 		
		}
	}
}

Status DestroyList(List &L){
	free(L);
	L=NULL;
	return OK;
}

运行结果:

 

 2,有序情况

注意:要求进行归并的两个数列必须是有序的,本代码是按照课本写的非递减数列;

思路:新申请一个空间L3,将L1与L2中的元素依次取出进行比较,然后如果将数值较小的放入L3中,取走元素的列表继续取下一个元素进行比较,没有取出元素的序列不变,依次循环进行,最后直到L1或者L2中有一个序列的元素取完为止,对于还剩有元素的序列将剩下的元素归并的新列表L3当中。

遇到的问题:

          1>malloc函数是没有初始化的,所以在创建的时候为了方便起见给每个新申请的空间均初始化为0;

           2>以后写函数的时候不要依据数组的存放方式第一个是*(L+0)这样写,这样容易在调用的时候混乱,直接在写的时候就按照第一个是第一个这样的方式对数列操作,这样调用函数的时候也思路清晰不宜出错;

实验代码:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#define OK 1
#define TRUE 1
#define ERROR 0
#define FALSE 0
#define OVERFLOW -2
#define INFEASIBLE -1
typedef int Status;
typedef Status ElemType;
typedef ElemType * List;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
Status InitList(List &L);
Status ListLength(List L);
Status ListInsert(List &L,ElemType i,ElemType e);
Status equal(ElemType e1,ElemType e2);
Status LocateElem(List L,ElemType e,Status (*equal)(ElemType,ElemType));
Status GetElem(List L,ElemType i,ElemType &e);
void uion(List &L1,List L2);
Status DestroyList(List &L);
void MergeList(List L1,List L2,List &L3);
int main(int argc, char *argv[]) {
	List L1;
	List L2;
	Status i=0,s,u; 
	if(InitList(L1)==0){
		printf("列表一动态内存空间申请失败;");	
	}
	List a1=L1;
	printf("请输入线性表L1待输入元素的个数:");
	scanf("%d",&s); 
	if(s>10){
		printf("输入个数超过申请空间的范围"); 
	}else{
		printf("请输入线性表1的元素:");
		for(i=0;i<s;i++){
			scanf("%d",(a1+i));
		}
	}
	printf("\n");
	
	if(InitList(L2)==0){
		printf("列表二动态内存空间申请失败;");	
	}
	List a2=L2;
	printf("请输入线性表L2待输入元素的个数:");
	scanf("%d",&u);
	if(u>10){
		printf("输入个数超过申请空间的范围"); 
	}else{
		printf("请输入线性表2的元素:");
		for(i=0;i<u;i++){
			scanf("%d",(a2+i));
		}
	} 
	printf("\n");
/********检验插入函数的功能是否实现************ 
	Status a,b;
	printf("输入待插入元的位置以及数值(试验先插入L1当中):");
	scanf("%d",&a);
	scanf("%d",&b);
	ListInsert(L1,a,b);
	printf("输出插入元素以后表L1的元素序列:");
	for(i=0;i<ListLength(L1);i++){
		printf(" %d",L1[i]);
	}
*/  
	
	List L3;
	if(InitList(L3)==0){                            //新创建一个表用于存放从L1与L2中去取出元素 
		printf("列表三动态内存空间申请失败;");	
	}
	MergeList(L1,L2,L3);
	printf("有序归并后元素的序列:"); 
	for(i=0;i<ListLength(L3);i++){
		printf(" %d ",L3[i]);
	}
	printf("\n");
	 
	if(DestroyList(L1)){
			printf("线性表L1已经销毁;\n"); 
		}
	if(DestroyList(L2)){
			printf("线性表L2已经销毁;\n"); 
		}
	if(DestroyList(L3)){
			printf("线性表L3已经销毁;\n"); 
		}
	return 0;
}

Status InitList(List &L){
	L=(ElemType*)malloc(sizeof(ElemType)*12);
	memset(L,0,sizeof(ElemType)*12);
	if(L==NULL){
		return ERROR;
	}else{
		return OK;
	}
}

Status ListLength(List L){             //返回列表的长度 
	Status m=0;
	while(*L++){
		m++;
	}
	return m;
}

Status ListInsert(List &L,ElemType i,ElemType e){          //在L的第i个元素前插入元素e 
	ElemType j;
	for(j=ListLength(L);j>=i;--j){
		*(L+j)=*(L+j-1); 
	}
	*(L+i-1)=e;
}

Status equal(ElemType e1,ElemType e2){
	if (e1==e2){
		return 0;
	}else{
		return 2;
	}
}

Status LocateElem(List L,ElemType e,Status (*equal)(ElemType,ElemType)){        //判断L1的表中是否有与元素e相同的元素 
    Status i=1;
	while(i<=ListLength(L)&&(*equal)(L[i-1],e)){
		i++;
	}
	
	if(i<=ListLength(L)){
		return i; 
	}else{
		return 0;
	}
}

Status GetElem(List L,ElemType i,ElemType &e){           //用e返回函数中第i个元素的值 
	e=L[i-1];
	return e; 
}

void MergeList(List L1,List L2,List &L3){
	Status L1_length=ListLength(L1);
	Status L2_length=ListLength(L2);
	Status L3_length=0;
	Status i1=1,i2=1,e1,e2,m;
	while((i1<=L1_length)&&(i2<=L2_length)){
		GetElem(L1,i1,e1); 	
		GetElem(L2,i2,e2);                               //L2中逐个取出元素 
		if(e1<=e2){
			ListInsert(L3,++L3_length,e1); 
			i1++;
		}else{
			ListInsert(L3,++L3_length,e2);	
			i2++;
			} 
		}
	if(i1<L1_length){
		while(i1<=L1_length){
			GetElem(L1,i1,e1);
			ListInsert(L3,++L3_length,e1);
			i1++;
		}
	}else if(i2<L2_length){
		while(i2<=L2_length){
			GetElem(L2,i2,e2);
			ListInsert(L3,++L3_length,e2);
			i2++;
		}
	}
}

Status DestroyList(List &L){
	free(L);
	L=NULL;
	return OK;
}

运行结果:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值