顺序表的基本操作
实验内容与步骤
实现顺序表上的插入、删除等操作。调试程序并对相应的输出作出分析;修改输入数据,预期输出并验证输出的结果。加深对有关算法的理解。
步骤:
第一步:定义顺序表的存储结构。
第二步:编写顺序表操作的具体函数定义。
第三步:使用定义的顺序表并调用顺序表的一些操作,实现具体运算。
具体函数的定义有:
1) insert(L,i,x)在顺序表的第i个元素之前插入一个新元素x.
2) delete (L,i) 删除顺序表的第i个元素。
3) listprint(L) 输出顺序表。
在DEVC++中,stdio.h包含了delete函数,所以需要对原有定义的delete函数进行修改,这里我改成了deleter;在DEVC++中在声明函数后面要直接说明数据类型,例如void listprint(sequenlist *L),不能按指导书上的代码直接写,不然会报错
这是最原来的代码输入后报错的图片
这里是我修改后的,代码如下
#define MAXSIZE 100 /*宏定义*/
#define OK 1
#define OVERFLOW -2
#include "stdio.h" /*包含输入输出文件*/
typedef int elemtype;
typedef struct { /*定义顺序表的结构*/
elemtype vec[MAXSIZE]; /*顺序表数据成员所占据的存储空间*/
int last; /*顺序表中最后一个元素在数组中的下标(或向量中的位置)从0开始*/
} sequenlist;
int insert(sequenlist *L,int i,elemtype x) { /*在顺序表的第i个元素之前插入一个新元素x*/
int j;
if(((*L).last)>=MAXSIZE-1) {
printf("the list is overflow!\n");
return(0); /*溢出判断*/
} else if((i<1)||(i>(*L).last+2)) {
printf("position is not correct!\n");
return(0); /*插入位置不正确*/
} else {
for(j=(*L).last; j>=i-1; j--) /*后移元素*/
(*L).vec[j+1]=(*L).vec[j];
(*L).vec[i-1]=x; /*插入新元素*/
(*L).last=(*L).last+1;/*修改last的值*/
}
return(1);
}
void deleter(sequenlist *L,int i) { /*删除顺序表的第i个元素*/
int j;
if((i<1)||(i>(*L).last+1))
printf("delete fail\n");
else {
for(j=i; j<=(*L).last; j++)
(*L).vec[j-1]=(*L).vec[j];/*前移元素,覆盖掉要删除元素的值*/
(*L).last--; /*修改last的值*/
}
}
void listprint(sequenlist *L) { /*输出线性表*/
int i;
for(i=0; i<=(*L).last; i++)
printf("i,e=%d,%d\n",i,L->vec[i]);
}
main() {
sequenlist sl= {{1,2,3,4,5,6,7,8,9,10},9}; //直接给顺序表赋初值
sequenlist *L;/*定义一个指向顺序表类型的指针变量*/
int i,j,x;
elemtype e;
L=&sl; /*给指针变量赋值*/
printf("please input the insert position and insert value\n");
scanf("%d,%d",&i,&x);
printf("the insert position: %d \ninsert value:%d\n",i,x);
insert(L,i,x);
listprint(L);
printf("please intput the delete position:");
scanf("%d",&j);
deleter(L,j);
listprint(L);
}
预习思考题
1) 定义一个定位函数locate(L,x),具有元素检索的功能。当顺序表中存在一个值为x的数据元素时,返回第一次找到的数据元素的位序,否则,给出一个值,表示值为x的元素不存在。在主程序中调用该函数,分析操作结果。
这里locate写的是按值查找,实际上相当于C语言中的在数组中按值查找位置,操作较为简单,这里我把不需要的地方都打了注释,代码及运行效果如下:
`#define MAXSIZE 100 /*宏定义*/
#define OK 1
#define OVERFLOW -2
#include "stdio.h" /*包含输入输出文件*/
typedef int elemtype;
typedef struct { /*定义顺序表的结构*/
elemtype vec[MAXSIZE]; /*顺序表数据成员所占据的存储空间*/
int last; /*顺序表中最后一个元素在数组中的下标(或向量中的位置)从0开始*/
} sequenlist;
int locate(sequenlist L,int x) {
int i,a=-1;
for(i=0; i<=(L).last; i++) {
if(x==(L).vec[i]) {
a=i;
break;
}
}
return a;
}
int insert(sequenlist L,int i,elemtype x) { /*在顺序表的第i个元素之前插入一个新元素x*/
int j;
if(((L).last)>=MAXSIZE-1) {
printf("the list is overflow!\n");
return(0); /*溢出判断*/
} else if((i<1)||(i>(L).last+2)) {
printf("position is not correct!\n");
return(0); /*插入位置不正确*/
} else {
for(j=(L).last; j>=i-1; j--) /*后移元素*/
(L).vec[j+1]=(L).vec[j];
(L).vec[i-1]=x; /*插入新元素*/
(L).last=(L).last+1;/*修改last的值*/
}
return(1);
}
void deleter(sequenlist L,int i) { /*删除顺序表的第i个元素*/
int j;
if((i<1)||(i>(L).last+1))
printf("delete fail\n");
else {
for(j=i; j<=(L).last; j++)
(L).vec[j-1]=(L).vec[j];/*前移元素,覆盖掉要删除元素的值*/
(L).last--; /*修改last的值*/
}
}
void listprint(sequenlist L) { /*输出线性表*/
int i;
for(i=0; i<=(L).last; i++)
printf("i,e=%d,%d\n",i,L->vec[i]);
}
main() {
sequenlist sl= {{1,2,3,4,5,6,7,8,9,10},9}; //直接给顺序表赋初值
sequenlist L;/*定义一个指向顺序表类型的指针变量*/
int i,j,x,k,y;
elemtype e;
L=&sl; /*给指针变量赋值*/
printf("please input the insert position and insert value\n");
scanf("%d,%d",&i,&x);
printf("the insert position: %d \ninsert value:%d\n",i,x);
insert(L,i,x);
listprint(L);
printf("please intput the delete position:");
scanf("%d",&j);
deleter(L,j);
listprint(L);
printf("输入定位数值");
scanf("%d",&k);
y=locate(L,k);
if(y==-1)
printf("查找不出来\n");
else printf("该数值的位置是%d\n",y);
}
我们显然可以看出来数值1在数组的第一个,位置也就是0,;数值0找不出来,所以输出查找不出来
2)定义一个逆置函数diverse(L),把顺序表进行逆置。在主程序中调用该函数,分析操作结果。
逆置也就是输入两个表示下标的i,j,一个从前往后遍历,一个从后往前遍历,这两者表示的数组中的数字一直互换,直到两者相等的时候就停下,代码及运行效果如下
#define MAXSIZE 100 /*宏定义*/
#define OK 1*
#define OVERFLOW -2
#include "stdio.h" /*包含输入输出文件*/
typedef int elemtype;
typedef struct { /*定义顺序表的结构*/
elemtype vec[MAXSIZE]; /*顺序表数据成员所占据的存储空间*/
int last; /*顺序表中最后一个元素在数组中的下标(或向量中的位置)从0开始*/
} sequenlist;*
void diverse(sequenlist *L) {
int i=0,j=L->last,t;
while(i<j) {
t=L->vec[i];
L->vec[i]=L->vec[j];
L->vec[j]=t;
i++;
j--;
}
}
void listprint(sequenlist *L) { /*输出线性表*/
int i;
for(i=0; i<=(*L).last; i++)*
printf("i,e=%d,%d\n",i,L->vec[i]);
}
main() {
sequenlist sl= {{1,2,3,4,5,6,7,8,9,10},9}; //直接给顺序表赋初值
sequenlist *L;/*定义一个指向顺序表类型的指针变量*/
L=&sl;
printf("逆置前的表为\n");
listprint(L);
diverse(L);
printf("逆置后的表为\n");
listprint(L);
}
为了方便阅读和观看,我对最开始的代码进行了较大调整
3) 定义一个函数delsame(L),把顺序表中重复的元素删除掉,只保留一个。在主程序中调用该函数,分析操作结果。
这里我们还是比较容易想到的,从第一个数开始,用剩下的数去跟它比较;在这次循环结束后,再从第二个数开始,以此类推,若有相同的数字删去即可。为了方便代码的调试,我把表中的数据进行了改动,代码及运行效果如下:
#define MAXSIZE 100 /*宏定义*/*
*#define OK 1
#define OVERFLOW -2
#include "stdio.h" /*包含输入输出文件*/
typedef int elemtype;
typedef struct { /*定义顺序表的结构*/
elemtype vec[MAXSIZE]; /*顺序表数据成员所占据的存储空间*/
int last; /*顺序表中最后一个元素在数组中的下标(或向量中的位置)从0开始*/
} sequenlist;
void deleter(sequenlist *L,int i) { /*删除顺序表的第i个元素*/
int j;
if((i<1)||(i>(*L).last+1))
printf("delete fail\n");
else {
for(j=i; j<=(*L).last; j++)
(*L).vec[j-1]=(*L).vec[j];/*前移元素,覆盖掉要删除元素的值*/
(*L).last--; /*修改last的值*/
}
}
void delsame(sequenlist *L)
{
int i,j;
for(i=0;i<L->last;i++)
for(j=i+1;j<=L->last;)
{
if(L->vec[i]==L->vec[j])
deleter(L,j+1);
else j++;
}
}
void listprint(sequenlist *L) { /*输出线性表*/
int i;
for(i=0; i<=(*L).last; i++)
printf("i,e=%d,%d\n",i,L->vec[i]);
}
main() {
*sequenlist sl= {{1,1,3,4,5,6,7,8,9,10},9}; //直接给顺序表赋初值*
*sequenlist *L;/*定义一个指向顺序表类型的指针变量*/*
*L=&sl;
printf("删除相同元素前\n");
listprint(L);
delsame(L);
printf("删除相同元素后\n");
listprint(L);
}
这里我们可以看到相同的数字1已经删去了
以上就是第一次数据结构实验报告