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

该实验涉及顺序表的初始化、销毁、清空、元素操作及两个非递减有序表的合并。实验要求实现线性表的基本操作,并测试各种边界情况。程序以菜单形式提供操作,包括插入、删除、获取元素、查找位置、求前驱和后继等。合并操作需要处理重复元素。测试用例覆盖了所有功能,包括错误输入和线性表状态的检查。
摘要由CSDN通过智能技术生成

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

验证性
重点: 顺序表的定义和实现
难点: 两个非递减有序表的去重合并
VC++6.0
一、设计思想
1.先背基本操作
2.先进行基本的程序编写,例如:结构体的创建,线性表的初始化,线性表的查询,删除,输出,删除和清空。
3.再依据线性表的基本操作经行线性表指定位置的插入、删除和线性表的合并等操作。
4.部分操作使用指针操作更加适合。
二、主要源代码

#include
#include<stdio.h>
#include<stdlib.h>
using namespace std;

#define LIST_INIT_SIZE 100//线性表储存空间的初始分配量
#define LISTINCREMENT 10//线性表空间的分配增量
#define true 1
#define false 0
#define ElemType int //类型重定义
#define dull 0//表示线性表为空的意思

//新类型的创建
typedef struct {
int * elem;//ElemType是空字符类型的意思,此处是选择链表初始变量类型的地方
int length;//长度
int listsize;//当前分配的存储容量以sizeofint为基准
}sqList;

//开始创建线性表
int InitList_Sq(sqList& l, int i) {
l.elem = (int*)malloc(LIST_INIT_SIZE * sizeof(int));
if (!l.elem)
exit(OVERFLOW);//存储分配失败
l.length = 0;
l.listsize = LIST_INIT_SIZE;
/for (int o = 0; o < i; o++)
{
cout << “请输入第” << o + 1 << “个元素:” << endl;
cin >> l.elem[o];
}
/
return true;
}

//销毁线性表
int destroylist(sqList& l) {

free(l.elem);
l.elem = NULL;
l.listsize = 0;
return true;

}

//清空线性表
int clearlist(sqList& l) {

l.listsize = 0;
return true;

}

//判断线性表是否为空
void listempty(sqList& l) {
if (l.length != 0)
{
cout << “该线性表不为空。” << endl;
}else{
cout << “该线性表为空。” << endl;
}
}

//求线性表长度
int listlength(sqList& l) {

if (l.length!=0) {//意思为线性表不为空
	cout <<"长度为:" << l.length << endl;
	return l.length;


}

}

//获取指定位置的元素
void getelement(sqList& l,int i) {
int k;
if (i <= l.length) {
k = l.elem[i - 1];//分配变量之后的elem元素可以当作数组使用
cout << “元素为:” << k << endl;
}
else
{
cout << “此元素不存在” << endl;
}

}

//获取线性表元素的位置
void getposition(sqList& l, int i) {
int k,op;
op = 0;
for (int j = 0; j < l.length; j++) {

		if (l.elem[j] == i) {
			k = j;
			cout << "位置为:" << k+1 << endl;
			op = 1;
		}
		
	}

	if (op != 1) {
		cout << "该元素不存在。" << endl;
	}

}

//求前驱
void beforeelement(sqList& l, int i) {
int j,op = 0;
for (int q = 0; q < l.length; q++) {
if (l.elem[q]i)
{
if (q - 1 >= 0) {//不超出范围的意思
j = l.elem[q - 1];
cout << “前驱为:” << j << endl;
op = 1;
}
else {
if (q
0)
{
cout << “第一个元素没有前驱” << endl;
op = 1;
}

			}
			
		}
		
	}
	if (op != 1) {
		cout << "该元素不存在于线性表中。" << endl;
	}

}

//求后继
void afterelement(sqList& l, int i) {
int j,op = 0;
for (int q = 0; q < l.length; q++) {
if (l.elem[q] == i)
{
if (q + 1 <= l.length) {//不超出范围的意思
j = l.elem[q + 1];
cout << “该元素的后继为:”<<j << endl;
op = 1;
break;
}
else
{
if (q == l.length-1) {
op = 1;
cout << “最后一位元素不存在后继。” << endl;
}
}

		}
		
	}

	if (op == 0) {
		cout << "该元素不存在于线性表中。" << endl;
	}

}

//指定位置插入元素
void insertelement(sqList& l, int i, int &j,int n) {//j
if (i > 0 && i <=n && l.length < LIST_INIT_SIZE)
{
for (int q = l.length; q >= i; q–)
l.elem[q] = l.elem[q - 1];
l.elem[i - 1] = j;
++l.length;
}
else
cout << “输入不合法!” << endl;

}

//指定位置删除元素
void deleteelement(sqList& l, int i) {//i是指删除的指定的位置

if (i > 0 && i <= l.length)
{
	for (int k = i; k < l.length; k++)
		l.elem[k - 1] = l.elem[k];
	--l.length;
cout << "删除完成" << endl;

}
else
	cout << "输入位置不合法!" << endl;

}

//显示线性表
void show(sqList &l) {

int i = 0;
for (; i < l.length; i++)
	cout << "第"<<i+1<<"个元素为:" << l.elem[i] << endl;


}

//合并线性表
void mergelist(sqList& i, sqList& j, sqList& k) {

int o,p;
int* pa, * pb, * pc, * pa_last, * pb_last;
pa = i.elem;
pb =j.elem;
k.length = i.length + j.length;
pc = k.elem;
pa_last = i.elem + i.length - 1;
pb_last = j.elem + j.length - 1;
while ((pa <= pa_last) && (pb <= pb_last)) {
	if (*pa < *pb)
	{
		*pc = *pa;
		*pc++;
		*pa++;
	}
	else
	{
		*pc = *pb;
		*pc++;
		*pb++;
	}
}
while (pa <= pa_last)
{
	*pc = *pa;
	*pc++;
	*pa++;
}
while (pb <= pb_last)
{
	*pc = *pb;
	*pc++;
	*pb++;
}
for (o = 0; o < k.length; o++)
{
	for (p = 0; p < o; p++)
	{
		if (k.elem[p] == k.elem[o])
		{
			cout << "重复的元素为:" << k.elem[o] << endl;
			cout << "请输入一个新元素:" << endl;
			cin >> k.elem[o];
			p = -1;
		}
	}
}
show(k);

}

int main() {
int i;
sqList one;
one.elem = NULL;
sqList two;
sqList three;

/*InitList_Sq(two, 5);
InitList_Sq(three, 6);

two.elem[0] = 2;
two.elem[1] = 3;
two.elem[2] = 3;
two.elem[3] = 4;
two.elem[4] = 5;
two.length = 5;

three.elem[0] = 1;
three.elem[1] = 4;
three.elem[2] = 5;
three.elem[3] = 6;
three.elem[4] = 6;
three.elem[5] = 7;
three.length = 6;
*/
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;

do{
cout << "请输入操作代码:" << endl;
cin >> i; 
switch (i)
{
case 1:
		int o;
		cout << "请输入线性表的长度:" << endl;
		cin >> o;
		//初始化
		InitList_Sq(one, o);
	break;
case 2:
	//销毁
	if (one.elem)
	{
		destroylist(one);
	}
	else
	{
		cout << "该线性表不存在或者已被删除,请先初始化线性表。" << endl;
	}
	
	break;
case 3:
	//清空
	if(one.elem)
	clearlist(one);
	else
	{
		cout << "该线性表不存在或者已经被删除,请先初始化线性表。" << endl;
	}
	break;
case 4:
	//是否为空
	if (one.elem) {
		listempty(one);
	}
	else
	{
		cout << "该线性表不存在或者已经被删除,请先初始化线性表。" << endl;
	}
	break;
case 5:
	//长度
	if (one.elem)
	{
		listlength(one);
	}
	else
	{
		cout << "该线性表不存在或者已经被删除,请先初始化线性表。" << endl;
	}
	break;
case 6:
	//指定位置元素
	int j, ele;
	if (one.elem) {
		cout << "请输入指定位置:" << endl;
		cin >> j;
		getelement(one, j);
		
	}
	else
	{
		cout << "该线性表不存在或者已经被删除,请先初始化线性表。" << endl;
	}
	break;
case 7:
	//指定元素位置
	if (one.elem) {
		cout << "请输入所求元素:" << endl;
		cin >> j;
		getposition(one, j);
		
	}
	else
	{
		cout << "该线性表不存在或者已经被删除,请先初始化线性表。" << endl;
	}
	break;
case 8:
	//求前驱
	if (one.elem) {
		cout << "请输入指定元素:" << endl;
		cin >> j;
		beforeelement(one, j);
		
	}
	else
	{
		cout << "该线性表不存在或者已经被删除,请先初始化线性表。" << endl;
	}
	break;
case 9:
	//求后继
	if (one.elem) {
		cout << "请输入指定元素:" << endl;
		cin >> j;
		afterelement(one, j);
	
	}
	else {
		cout << "该线性表不存在或者已经被删除,请先初始化线性表。" << endl;
	}

	break;
case 10:
	//指定位置插入元素
	if (one.elem) {
		cout << "请输入插入的位置" << endl;
		cin >> j;
		cout << "请输入插入的元素" << endl;
		cin >> ele;
		insertelement(one, j, ele,o);
	}
	else {
		cout << "该线性表不存在或者已经被删除,请先初始化线性表。" << endl;
	}
	break;
case 11:
	//删除指定位置元素
	if (one.elem) {
		cout << "输入删除的指定位置:" << endl;
		cin >> j;
		deleteelement(one, j);
	
	}
	else {
		cout << "该线性表不存在或者已经被删除,请先初始化线性表。" << endl;
	}
	break;
case 12:
	//显示线性表
	if (one.elem) {
		show(one);
	}
	else {
		cout << "该线性表不存在或者已经被删除,请先初始化线性表。" << endl;
	}
	break;
case 13:
	//合并两个非递减有序的线性表
	if (one.elem) {
		mergelist(two, three, one);
	}
	else {
		cout << "该线性表不存在或者已经被删除,请先初始化线性表。" << endl;
	}
	break;
default:
	break;
}
} while (i > 0);//输出小于0的时候退出的功能

}

最后的合并线性表的实验还没有达到完美,到时候去找老师搞一下。

  • 16
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值