新手向数据结构实验02线性表合并等操作

实验2、基于顺序表的非递减有序表的合并

(1)实验目的

通过该实验,深入理解顺序表的逻辑结构、物理结构等概念,掌握顺序表基本操作的编程实现,注意顺序表插入、删除等操作过程中数据元素的移动现象,培养学生编写程序时,要考虑程序的健壮性,全面考虑问题,熟练掌握通过函数参数返回函数结果的办法。

(2)实验内容

编程实现顺序表下教材第二章定义的线性表的基本操作,并根据已经实现的基本操作(函数),通过调用函数,实现两个非递减有序的线性表的合并,注意,合并时,如果有重复的元素(一个表内部的重复元素和两个表之间的重复元素),请保留一个。

(3)实验要求

(a)求前驱是指,输入一个元素值(而不是位置),求该元素在顺序表中的直接前驱元素值。求后继是指:输入一个元素值(而不是位置),求该元素在顺序表中的直接后继元素值;(b)为了方便修改数据元素的类型,请使用类型重定义,可以方便修改线性表中的数据元素的类型;(c)大部分函数的返回结果应是函数执行是否成功的一种状态,执行成功了,才返回具体的结果值;(d)对每个功能进行测试时,要求把不合法的情况也测试一下。

#include<iostream>
#include<cstdlib>//exit函数 
using namespace std;
#define LIST_INIT_SIZE 100 //线性表存储空间的初始分配量 
#define LISTINCREMENT 10 //线性表存储空间的分配增量 
#define OVERFLOW -1 //为exit()定义常量 
int a_ok=0; //全局变量,判断空间申请是否成功
int b_ok=0; //申请成功 

typedef int ElemType;
typedef struct{
	ElemType *elem; //存储空间基址 规定ElemType的默认是int型
	int length; //当前长度 
	int listsize; //当前分配的存储容量(以sizeof(ElemType)为单位) 
}SqList;

//1 初始化线性表
void InitList_Sq(SqList &L){
	L.elem=(ElemType*)malloc(LIST_INIT_SIZE *sizeof(ElemType));
	/*
	分配内存空间函数malloc:(类型说明符*)malloc(size)
	(类型说明符*)表示把返回值强制转换为该类型指针。
	“类型说明符”表示把该区域用于何种数据类型。
	*/
	if(!L.elem){                                
		cout<<"初始化空间失败,请重新操作"<<endl;
		exit(OVERFLOW);// 当程序运算出现上溢时,退出程序并报错给主调进程
	}
	L.length=0; //表长 
	L.listsize=LIST_INIT_SIZE; //分配存储容量 
    cout<<"储存空间分配成功"<<endl;
}

//2 销毁线性表 
void  Destroylist_Sq(SqList &L){
	free(L.elem);
	/*
	free(void*ptr);
	功能:释放ptr所指向的一块内存空间,
	ptr是一个任意类型的指针变量,
	它指向被释放区域的首地址。
	被释放区应是由malloc或calloc函数所分配的区域。
	*/
	L.elem=NULL;
	if(!L.elem){
	cout<<"销毁成功";
}
	else {
		cout<<"销毁失败";
		exit(0);// 正常退出,若exit(x),x!=0,则为异常输出 
	}
	cout<<endl;
}

//3 清空线性表
void ClearList_Sq(SqList &L){
	L.length=0;
	L.listsize=LIST_INIT_SIZE; //重新分配存储容量 
	cout<<"清空成功";
} 

//4 判断线性表是否为空
void EmptyList_Sq(SqList &L){
	if(L.length==0){
		cout<<"该线性表是空表" ;
	}
	else  cout<<"不是空表";
	cout<<endl;
} 

//5 求线性表的长度
void GetLength_Sq(SqList &L){
	cout<<"表长为"<<L.length<<endl; 
} 

//6 求指定位置元素的值  
void GetElem_Sq(SqList &L){
	int index;  //元素的位置 
	cout<<"该表的长度为:"<<L.length<<endl; 
	cout<<"请输入你想查询的元素位置:";
	cin>>index;
	if(index>0&&index<L.length+1){
		cout<<"你查询的元素为:"<<L.elem[index-1]<<endl;
	} 
	else cout<<"你输入的位置超出了表a的范围.";
	cout<<endl<<endl;
}

//7 根据元素的值来获取位置
void GetIndex_Sq(SqList &L){
	int g_elem;//元素的值 
	int index=0;
	cout<<"请输入你要查询的元素:";
	cin>>g_elem;
	for(int i=0;i<L.length;i++){
		if(g_elem==L.elem[i]){
			index=i+1;
			cout<<"该元素所在位置为:"<<index<<endl;
			return;//退出程序 
		}
	}
	cout<<"该表中不存在该元素.";
	cout<<endl;
} 

//8 求前驱
void  PriorElem_Sq(SqList &L){
	int index;
	cout<<"请输入线性表a中某一元素的位置:(范围:2~"<<L.length<<")"<<endl;
	cin>>index;
	if(index<L.length+1&&index>1){ //首位无前驱 
		cout<<"该位置的前驱是:"<<L.elem[index-2]<<endl;
		cout<<endl;
	}
	else cout<<"输入有误!该位置无前驱或者该元素不存在!"<<endl;
}

//9 求后驱
void NextElem_Sq(SqList &L){
	int index;
	cout<<"请输入线性表a中某一元素的位置:(范围:1~"<<L.length-1<<")"<<endl;
	cin>>index;
	if(index<L.length&&index>0) { //末位无后驱 
		cout<<"该位置的后驱是:"<<L.elem[index]<<endl;
		cout<<endl;
	}
	else cout<<"输入有误!该位置无后驱或者该元素不存在!"<<endl;
}

//10 在指定位置前插入元素
void ListInsert(SqList &L1,SqList &L2){
	if(a_ok==0&&b_ok==0){
		cout<<"线性表a或b未能初始化!请重新输入!"<<endl;
	}
	else{
		int index=0;
		int i_elem=0;
		int which=0;
		cout<<"请输入你要插入的线性表的序号:"<<endl;
		cout<<"1.线性表a."<<endl;
		cout<<"2.线性表b."<<endl;
		cin>>which;
		if(which==1){
			cout<<"请输入要插入的位置:(范围:1~"<<L1.length+1<<")"<<endl;
			cin>>index;
			cout<<"请输入你要插入的元素值:";
			cin>>i_elem;
			if(index<1||index>L1.length+1){
				cout<<"位置越界!插入失败!"<<endl; 
				return;
			} 
			else{
				int *q=&(L1.elem[index-1]);
				for(int *p=&(L1.elem[L1.length-1]);p>=q;--p){
					*(p+1)=*p;
				}
				*q=i_elem;
				++L1.length;
				cout<<"插入成功!"<<endl;
			}
		}
		else if(which==2){
			cout<<"请输入要插入的位置:(范围:1~"<<L2.length+1<<")"<<endl;
			cin>>index;
			cout<<"请输入你要插入的元素值:";
			cin>>i_elem;
			if(index<1||index>L2.length+1){
				cout<<"位置越界!插入失败!"<<endl; 
				return;
			} 
			else{
				int *q=&(L2.elem[index-1]);
				for(int *p=&(L2.elem[L2.length-1]);p>=q;--p){
					*(p+1)=*p;
				}
				*q=i_elem;
				++L2.length;
				cout<<"插入成功!"<<endl;
			}
		}
		else cout<<"输入有误!请重新输入!";
	}
}

//11 删除线性表指定位置的元素
void ListDelete(SqList &L1,SqList &L2){
	if(a_ok==0&&b_ok==0){
		cout<<"线性表a或b未能初始化!请重新输入!"<<endl;
	}
	else{
		int index=0;
		int dl_elem=0;
		int which=0;
		cout<<"请输入你要删除的线性表的序号:"<<endl;
		cout<<"1.线性表a."<<endl;
		cout<<"2.线性表b."<<endl;
		cin>>which;
		if(which==1){
			cout<<"请输入你要删除的元素的位置:(范围:1~"<<L1.length<<")"<<endl;
			cin>>index;
			if(index<1&&index>L1.length){
				cout<<"位置越界!删除失败!"<<endl;
			}
			else{
				int *q=&(L1.elem[index-1]);
				for(int *p=&(L1.elem[L1.length-1]);q<p;++q){
					*q=*(q+1);
				}
				--L1.length;
				cout<<"删除元素成功!"<<endl;
				}
			}	
		else if(which==2){
			cout<<"请输入你要删除的元素的位置:(范围:1~"<<L2.length<<")"<<endl;
			cin>>index;
			if(index<1&&index>L2.length){
				cout<<"位置越界!删除失败!"<<endl;
			}
			else{
				int *q=&(L2.elem[index-1]);
				for(int *p=&(L2.elem[L2.length-1]);q<p;++q){
					*q=*(q+1);
				}
				--L2.length;
				cout<<"删除元素成功!"<<endl;
				}
		}
		else cout<<"输错了!请重新输入!"<<endl;
	}
}

//12 显示线性表
void ListPrint_Sq(SqList &L){
	cout<<"该线性表打印为"<<endl;
	for(int i=0;i<L.length;i++){
		cout<<L.elem[i]<<" "<<endl; 
	}
}

//13 合并两个非递减的线性表
void ListHebing(SqList &L1,SqList &L2,SqList &L3){
	if(a_ok==0){
		cout<<"线性表a未能初始化!请重新输入!"<<endl;
	}
	else{
		if(b_ok==0){
			cout<<"线性表a未能初始化!请重新输入!"<<endl;
		}
		else{
			int *pa=L1.elem;
			int *pb=L2.elem;
			L3.listsize=L3.length=L1.length+L2.length;
			int *pc=L3.elem=(ElemType*)malloc(L3.listsize*sizeof(ElemType));
			if(!L3.elem) 
				exit(OVERFLOW);
			int *pa_last=L1.elem+L1.length-1;
			int *pb_last=L2.elem+L2.length-1;
			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++;
			cout<<"线性表合并完毕:";
			for(int j=0;j<L3.length;j++){   //合并后的查重操作
	    		if(L3.elem[j] == L3.elem[j+1]){
	    			for(int i=j+1;i<L3.length-1;i++){
	    				L3.elem[i]=L3.elem[i+1];
					} 
					L3.length--;
				}  
    		}
  			for(int i=0;i<L3.length;i++){
  	  			cout<<" "<<L3.elem[i];
			}	
		}
	}
	cout<<endl;
} 
//主函数 
int main(){
	int flag=1;
	SqList La; //声明变量 
    SqList Lb; //某被调函数不需要修改原结构体,使用原结构体当中的数据
	int infer;
	while(flag){
	cout<<"--------------------------------------"<<endl;
	cout<<"*********1.初始化线性表***************"<<endl;
	cout<<"*********2.销毁线性表*****************"<<endl;
	cout<<"*********3.清空线性表*****************"<<endl;
	cout<<"*********4.判断线性表是否为空*********"<<endl;//4-9只针对表a 
	cout<<"*********5.求线性表长度***************"<<endl;
	cout<<"*********6.获取线性表中指定位置的元素*"<<endl;
	cout<<"*********7.获取线性表元素的位置*******"<<endl;
	cout<<"*********8.求前驱*********************"<<endl;
	cout<<"*********9.求后驱*********************"<<endl;
	cout<<"*********10.在线性表指定位置插入元素**"<<endl;
	cout<<"*********11.删除线性表指定位置的元素**"<<endl;
	cout<<"*********12.显示线性表****************"<<endl;
	cout<<"*********13.合并两个非递减有序的线性表"<<endl;
	cout<<"**********退出,输入一个负数**********"<<endl;
    cout<<"--------------------------------------"<<endl;
    cout<<"请输入对应的序号来进行相应的操作:";
    cin>>infer;
    switch(infer){
    	case 1:
    		InitList_Sq(La);
    		cout<<"成功建立a表"<<endl; 
    		a_ok=1;
    		InitList_Sq(Lb);
    		cout<<"成功建立b表" <<endl;
    		b_ok=1;
			break;
	 	case 2:
	 		cout<<"请输入a或b来表示想销毁的线性表:"<<endl;
	 		char panding1;
	 		if(panding1=='a'&&a_ok==1)
			Destroylist_Sq(La);
			if(panding1=='a'&&a_ok==0)
			cout<<"请先初始化a表"<<endl;
			if(panding1='b'&&b_ok==1)
			Destroylist_Sq(Lb);
			if(panding1=='b'&&b_ok==0)
			cout<<"请先初始化b表"<<endl;
			break;
		case 3:
			cout<<"请输入a或b来表示想清空的线性表:"<<endl;
			char panding2;
			if(panding2='a'&&a_ok==1)
			ClearList_Sq(La);
			if(panding2=='a'&&a_ok==0)
			cout<<"请先初始化a表"<<endl;
			if(panding2='b'&&b_ok==1)
			ClearList_Sq(Lb);
			if(panding2=='b'&&b_ok==0)
			cout<<"请先初始化b表"<<endl;
			break;
		case 4:
			if(a_ok==1)
				EmptyList_Sq(La);
			else   cout<<"请先初始化a表"<<endl;
			break;		
		case 5:
			if(a_ok==1)
				GetLength_Sq(La);
			else   cout<<"请先初始化a表"<<endl;
			break;
		case 6:
			if(a_ok==1)
				GetElem_Sq(La);
			else   cout<<"请先初始化a表"<<endl;
			break;
		case 7:
			if(a_ok==1)
				GetIndex_Sq(La);
			else   cout<<"请先初始化a表"<<endl;
			break;
		case 8:
			if(a_ok==1)
				PriorElem_Sq(La);
			else   cout<<"请先初始化a表"<<endl;
			break;
		case 9:
			if(a_ok==1)
				NextElem_Sq(La);
			else   cout<<"请先初始化a表"<<endl;
			break; 
		case 10:
			ListInsert(La,Lb);
			cout<<endl;
			break;
		case 11:
			ListDelete(La,Lb);
			cout<<endl;
			break;
		case 12:
			cout<<"请输入序号来表示想打印的线性表:"<<endl;
			cout<<"1-线性表a"<<endl
				<<"2-线性表b"<<endl;
			int choose;
			cin>>choose;
			if(choose==1||choose==2){
			if(choose==1&&a_ok==1)
			ListPrint_Sq(La);
			if(choose==1&&a_ok==0)
			cout<<"请先初始化a表"<<endl;
			if(choose==2&&b_ok==1)
			ListPrint_Sq(Lb);
			if(choose==2&&b_ok==0)
			cout<<"请先初始化b表"<<endl;
			}
			else{
				cout<<"输入错误,请重新输入您想要打印的线性表!"<<endl;
				cin>>choose;
				continue;
			}
			break;
		case 13:
			SqList Lc;
			ListHebing(La,Lb,Lc);
			cout<<endl;
			break;
		default:
			if(infer<0){
				flag=0;//while(flag)为假,结束循环 
				cout<<"成功退出程序,欢迎下次使用!"<<endl;
				break; 
			}
			else cout<<"输入有误!请重新尝试!"<<endl;
			break;
		}
	}
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值