实验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 (q0)
{
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的时候退出的功能
}
最后的合并线性表的实验还没有达到完美,到时候去找老师搞一下。