数据结构---基于顺序表的非递减有序表的合并

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

(1)实验目的

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

(2)实验内容

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

(3)实验要求

(a)求前驱是指,输入一个元素值(而不是位置),求该元素在顺序表中的直接前驱元素值。求后继是指:输入一个元素值(而不是位置),求该元素在顺序表中的直接后继元素值;(b)为了方便修改数据元素的类型,请使用类型重定义,可以方便修改线性表中的数据元素的类型;(c)大部分函数的返回结果应是函数执行是否成功的一种状态,执行成功了,才返回具体的结果值;(d)对每个功能进行测试时,要求把不合法的情况也测试一下。具体见下面的测试用例;(e)采用菜单形式对应各个操作,使其编成一个完整的小软件,参考界面如下。注意:程序运行过程中菜单不要做成刷屏的效果,测试过的数据不要清除,这样方便截图和查看。

注:销毁是指free(L.elem);  L.elem=NULL;  L.length=0; L.listsize=0; return TRUE。清空是指:L.length=0 ;return TRUE。

(3)验收/测试用例

通过菜单调用各个操作,测试点:

  1. 没有初始化前进行其他操作,程序是否能控制住;即,如果没有初始化线性表,其他的功能是无法正常进行的,如果选择进行其他操作,要提示先进行初始化;
  2. 先选择菜单1,初始化一个顺序表(初始化顺序表,是指初始化一个空的线性表,里面的元素个数是0);
  3. 选择菜单10,插入数据(位置, 数据),要测插入位置不合法的情况(0,1)、(2,1),正确插入3个数据(1,20)、(1,10)、(3,30);
  4. 显示顺序表中的数据,屏幕输出10, 20, 30;
  5. 判空,屏幕输出顺序表非空;
  6. 输出顺序表长度,屏幕输出3;
  7. 获取指定位置元素,要测指定位置在【1,3】范围之外的情况和之内的情况;
  8. 定位,输入:40, 输出:不存在,输入20,输出位置为2;
  9. 求直接前驱,要测求第一个元素的前驱、不存在顺序表中的元素的直接前驱,其他元素的直接前驱;输入10,输出:第一个元素没有前驱,输入20,输出前驱是10,输入40,输出该元素不存在;
  10. 求直接后继,要测最后一个元素的后继、不存在顺序表中的元素的直接后继,其他元素的直接后继;同上求前驱;
  11. 删除,要测位置在【1,3】范围之外的情况和之内的情况;
  12. 清空操作后再测长度,判断是否为空;清空后,测试菜单6到11的功能,看是否能够正确提示。
  13. 销毁顺序表,销毁线性表之后还能不能做插入,删除等操作,如果选其他操作,就要提示线性表已经销毁不存在;
  14. 测试合并操作,第一个线性表中的元素是(2,3,3,4,5),第二个线性表中的内容是(1,4,5,6,6,7),合并后的结果,请输出。

 

#include <iostream>
using namespace std;
# define  LIST_INIT_SIZE   100  
# define   LISTINCREMENT    10  
#define OK 1  //执行成功
#define NO -1  //不存在
#define ERROR 0  //超出范围or执行失败
bool flag;
typedef int Status;
typedef int ElemType;

typedef struct {
	ElemType* elem;
	int length;
	int listsize;
}SqList;

SqList L;
SqList lc;//合并表的结果

//初始化顺序表
Status InitList(SqList& l) {
	l.elem = (ElemType*)malloc(LIST_INIT_SIZE * sizeof(ElemType));//为数据元素开辟一维数组空间

	if (!l.elem) {
		cout << "线性表L储存分配失败,请重新操作" << endl;
		return ERROR;
	}
	else {
		l.length = 0;
		l.listsize = LIST_INIT_SIZE;
		cout << "线性表的存储空间分配成功!" << endl;
		return OK;
	}
}
//销毁
Status DestroyList(SqList& L)
{
	free(L.elem);
	L.elem = NULL;
	L.length = 0;
	L.listsize = 0;
	flag = false;
	return OK;
}
//清空
Status ListEmpty(SqList& L) {
	L.length = 0;
	return OK;
}
//判断数组是否为空
bool JudgeNull(SqList L) {
	if (L.length == 0) {
		return true;
	}
	else {
		return false;
	}
}
//求长度
int ListLength(SqList L) {
	return L.length;
}
//获取线性表中指定位置的元素
Status GetElem(SqList L, int  i, ElemType& e) {
	if (i >= 0 && i < L.length)
	{
		e = L.elem[i - 1];
		return OK;
	}
	else
	{
		return NO;
	}
}
//获取线性表元素的位置
Status LocateElem(SqList L, ElemType e, int& z) {
	for (int i = 0; i < L.length; i++)
	{
		if (L.elem[i] == e)
		{
			z = i + 1;
			return OK;
		}
	}
	return NO;
}
//前驱
Status PriorElem(SqList L, ElemType cur_e, ElemType& pre_e) {
	for (int i = 0; i < L.length; i++)
	{
		if (L.elem[i] == cur_e)
		{
			if (i == 0) {
				return ERROR;
			}
			else
			{
				pre_e = L.elem[i - 1];
				return OK;
			}
		}
	}
	return NO;
}
//后继
Status NextElem(SqList L, ElemType cur_e, ElemType& next_e) {
	for (int i = 0; i < L.length; i++)
	{
		if (L.elem[i] == cur_e)
		{
			if (i == L.length - 1) {
				next_e = -1;
				return ERROR;
			}
			else
			{
				next_e = L.elem[i + 1];
				return OK;
			}
		}
	}
	return NO;
}
//插入
Status ListInsert(SqList& L, int i, ElemType e) {
	if (i < 1 || i > L.length + 1) {
		return ERROR;
	}
	if (L.length < L.listsize) {
		int* q;
		q = &L.elem[i - 1];
		for (int* p = &(L.elem[L.length - 1]); p >= q; p--)
		{
			*(p + 1) = *p;
		}
		*q = e;
		L.length += 1;
		return OK;
	}
}
//删除
Status DelElem(SqList& L, int i) {
	if (i < 1 || i > L.length) {
		return ERROR;
	}
	ElemType* q = &(L.elem[L.length - 1]);
	//将删除位置后的所有元素向前移动
	for (ElemType* p = &(L.elem[i - 1]); p < q; p++) {
		*p = *(p + 1);
	}
	--L.length;
	return OK;
}
//显示表
Status ShowTable(SqList l) {
	cout << "表L:";
	for (int i = 0; i < l.length; i++)
	{
		cout << l.elem[i] << " ";
	}
	cout << "" << endl;
	return OK;
}
//合并表
Status ListMerge(SqList &lc) {
	SqList la;
	SqList lb;
	//初始化表A
	cout << endl;
	la.elem = (ElemType*)malloc(LIST_INIT_SIZE * sizeof(ElemType));
	if (!la.elem)
	{
		cout << "线性表A存储分配失败,请您重新操作!" << endl;
	}
	else
	{
		la.length = 0;
		la.listsize = LIST_INIT_SIZE;
		cout << "线性表A的存储空间分配成功!" << endl;
		cout << "请输入A中的元素,以负数结束:" << endl;
		int a;
		cin >> a;
		while ( a > 0 )
		{
			la.length++;
			la.elem[la.length - 1] = a;
			cin >> a;
		}
	}

	//初始化表B
	cout << endl;
	lb.elem = (ElemType*)malloc(LIST_INIT_SIZE * sizeof(ElemType));
	if (!lb.elem)
	{
		cout << "线性表B存储分配失败,请您重新操作!" << endl;
	}
	else
	{
		lb.length = 0;
		lb.listsize = LIST_INIT_SIZE;
		cout << "线性表B的存储空间分配成功!" << endl;
		cout << "请输入B中的元素,以负数结束:" << endl;
		int a;
		cin >> a;
		while (a > 0)
		{
			lb.length++;
			lb.elem[lb.length - 1] = a;
			cin >> a;
		}
	}
	lc.elem = (ElemType*)malloc(LIST_INIT_SIZE * sizeof(ElemType));
	if (!lc.elem) {
		cout << "合并线性表C创建失败,请重新创建!" << endl;
	}
	else {
		cout << "合并线性表C的内存空间分配成功!" << endl;
		cout << "合并线性表合并后:";
		lc.listsize = lc.length = la.length + lb.length;
		ElemType* pa = &la.elem[0];
		ElemType* pb = &lb.elem[0];
		ElemType* pc = &lc.elem[0];
		ElemType* pa_end = &la.elem[la.length - 1];
		ElemType* pb_end = &lb.elem[lb.length - 1];

		while (pa <= pa_end && pb <= pb_end)//合并线性表A、B。 
		{
			if (*pa <= *pb)
			{
				*pc = *pa;
				pa++;
				pc++;
			}
			else
			{
				*pc = *pb;
				pb++;
				pc++;
			}
		}
		while (pa <= pa_end)//把表A中的剩余元素插入C。 
		{
			*pc = *pa;
			pa++;
			pc++;
		}
		while (pb <= pb_end)//把表B中的剩余元素插入C。 
		{
			*pc = *pb;
			pb++;
			pc++;
		}
		for (int i = 0; i <= lc.length - 1; i++)//查重,去重复值。 
		{
			for (int j = i + 1; j <= lc.length - 1; j++) {
				if (lc.elem[i] == lc.elem[j]) {
					ElemType* q = &(lc.elem[lc.length - 1]);
					for (ElemType* p = &(lc.elem[i]); p < q; p++) {
						*p = *(p + 1);
					}
					--lc.length;
					j--;
					i--;//删除了重复的元素lc.elem[i]和lc.elem[j]向前移动一位
				}
			}
		}
		for (int i = 0; i <= lc.length - 1; i++)//输出
		{
			cout << lc.elem[i] << " ";
		}
		cout << endl;
	}

	return OK;
}


int main()
{
	int n;
	SqList la;
	SqList lb;
	ElemType tem;//定义一个临时元素
	int address;//储存地址的值

	cout << "1--初始化化一个线性表" << endl;
	cout << "2--销毁线性表" << endl;
	cout << "3--清空线性表" << endl;
	cout << "4--判断线性表是否为空" << endl;
	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;
	cin >> n;
	while (n >= 0) {
		switch (n)
		{
		case 1:
			InitList(L);
			flag = true;
			break;
		case 2:
			if (flag) {
				DestroyList(L);
				cout << "表已销毁。" << endl;
			}
			else {
				cout << "请先初始化表。" << endl;
			}
			break;
		case 3:
			if (flag) {
				ListEmpty(L);
				cout << "表已清空。" << endl;
			}
			else {
				cout << "请先初始化表。" << endl;
			}
			break;
		case 4:
			if (flag) {
				if (JudgeNull(L)) {
					cout << "表L为空" << endl;
				}
				else
				{
					cout << "表L不为空" << endl;
				}
			}
			else {
				cout << "请先初始化表。" << endl;
			}
			break;
		case 5:
			if (flag) {
				cout << "表L的长度为" << ListLength(L) << endl;
			}
			else {
				cout << "请先初始化表。" << endl;
			}
			break;
		case 6:
			if (flag) {
				cout << "请输入元素在表中的位置:" << endl;
				cin >> address;
				if (GetElem(L, address, tem) == OK)
					cout << "元素为:" << tem << endl;
				else if (GetElem(L, address, tem) == NO)
					cout << "不存在。" << endl;
				break;
			}
			else {
				cout << "请先初始化表。" << endl;
			}
			break;
		case 7:
			if (flag) {
				cout << "请输入元素:" << endl;
				cin >> tem;
				if (LocateElem(L, tem, address) == OK)
					cout << "元素在表中的位置为:" << address << endl;
				else if (LocateElem(L, tem, address) == NO)
					cout << "不存在。" << endl;
			}
			else {
				cout << "请先初始化表。" << endl;
			}
			break;
		case 8:
			if (flag) {
				ElemType res;
				cout << "请输入元素:" << endl;
				cin >> tem;
				PriorElem(L, tem, res);
				if (PriorElem(L, tem, res) == ERROR) 
					cout << "第一个元素没有前驱。" << endl;
				else if (PriorElem(L, tem, res) == OK) 
					cout << "该元素的前驱为:" << res << endl;
				else 
					cout << "不存在。" << endl;
			}
			else {
				cout << "请先初始化表。" << endl;
			}
			break;
		case 9:
			if (flag) {
				ElemType res;
				cout << "请输入元素:" << endl;
				cin >> tem;
				NextElem(L, tem, res);
				if (NextElem(L, tem, res) == ERROR) {
					cout << "最后一个元素没有后继。" << endl;
				}
				else if (NextElem(L, tem, res) == OK) {
					cout << "该元素的后继为:" << res << endl;
				}
				else {
					cout << "不存在。" << endl;
				}
			}
			else {
				cout << "请先初始化表。" << endl;
			}
			break;
		case 10:
			if (flag) {
				cout << "请输入位置:" << endl;
				cin >> address;
				cout << "请输入元素:" << endl;
				cin >> tem;
				if (ListInsert(L, address, tem) == OK)
					cout << "插入成功。" << endl;
				else
					cout << "位置超出范围。" << endl;
			}
			else {
				cout << "请先初始化表。" << endl;
			}
			break;
		case 11:
			if (flag) {
				cout << "请输入位置:" << endl;
				cin >> address;
				if (DelElem(L, address)== OK)
					cout << "删除成功。" << endl;
				else
					cout << "位置超出范围。" << endl;
			}
			else {
				cout << "请先初始化表。" << endl;
			}
			break;
		case 12:
			if (flag) {
				ShowTable(L);
			}
			else {
				cout << "请先初始化表。" << endl;
			}
			break;
		case 13:
			ListMerge(lc);
			break;
		default:
			break;
		}
		cout << "请输入选项:\n";
		cin >> n;
	}
}

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

HotRabbit.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值