顺序表的基本操作.docx
《顺序表的基本操作.docx》由会员分享,可在线阅读,更多相关《顺序表的基本操作.docx(18页珍藏版)》请在冰豆网上搜索。
![顺序表的基本操作.docx](https://file1.bdocx.com/fileroot1/2023-2/1/d55d44f6-047b-4cb2-bfb9-9e91e415af20/d55d44f6-047b-4cb2-bfb9-9e91e415af201.gif)
顺序表的基本操作
实验题目
顺序表的基本操作
小组合作
姓名
班级
学号
888888888
一、实验目的
实验
(一)
1.掌握顺序表的C语言描述,定义等基本操作
2.将顺序表的基本操作使用C语言来实现
二.实验环境
DevC++
三、实验内容与步骤
实验
(一)
内容:
顺序表中是数据结构中的一种顺序存储结构,存储在相邻的内存单元中,其单元的地址是连续的,C语言中通常采用数组来表示顺序表数据的存储实现。
顺序表作为一种抽象数据类型(ADT),有创建、添加,删除,查询等相关操作。
表示顺序表时,采用结构体形式,结构体包含了顺序表的长度,数据域。
(1)创建一个顺序表,并对顺序表进行初始化
(2)对第1步创建好的顺序表,进行相关的操作
步骤:
1.向顺序表中插入结点
2.删除顺序表中的某个结点
3.求顺序表的长度
4.查询结点的位置
5.清空顺序表
四、实验过程与分析
(一)用C语言编程实现以上操作
1.创建顺序表之前,先引入头文件、完成一些宏定义和定义一下顺序表:
#include
#include
#defineMAXSIZE100
#defineOK1
#defineERROR0
#defineTRUE1
#defineFALSE0
typedefintElemType;
typedefintStatus;
//定义顺序表为结构体类型
typedefstructNode{
ElemType*data;//数组指针形式表示数据
intlen;//顺序表的长度
}SqList;//结构体别名:
SqList代替structNode字样
2.为了便于更加直观的操作,先写一个函数,用来实现人机交互:
voidoptions(){
printf("**********************************************\n");
printf("【1】置空顺序表\n");
printf("【2】判断顺序表是否为空\n");
printf("【3】求顺序表的长度\n");
printf("【4】输出顺序表中第i个元素的值\n");
printf("【5】获取顺序表中第一个与e相同的元素位置\n");
printf("【6】获取元素的的直接前驱\n");
printf("【7】获取元素的直接后继\n");
printf("【8】插入元素\n");
printf("【9】删除顺序表的元素\n");
printf("【10】访问顺序表的元素\n");
printf("【11】输出顺序表\n");
printf("【12】退出\n");
printf("**********************************************\n");
}
3.编写用于初始化顺序表,并对顺序表的数据进行初始化的操作:
//构造一个新的顺序表
StatusInitList(SqList*L){
inti,n;
L->data=(ElemType*)malloc(sizeof(ElemType)*MAXSIZE);//动态申请空间
if(!
L->data){//如果申请的空间为空
printf("顺序表创建失败\n");
returnERROR;
}else{
L->len=0;
printf("顺序表初始化完成\n");
}
//对顺序表的数据进行初始化
printf("请输入要插入的元素个数:
");
scanf("%d",&n);
printf("请输入元素:
");
for(i=0;iscanf("%d",&L->data[i]);
L->len++;
}
printf("数据初始化完毕\n\n");
}
4.置空线性表:
StatusClearList(SqList*L){
inti;
if(L->len==0){
printf("顺序表已空\n\n");
returnERROR;
}
for(i=L->len-1;i>=0;i--){
L->data[i]=-1;
L->len--;
}
printf("顺序表置空完毕\n");
returnOK;
}
5.判断线性表是否为空,如果为空返回TRUE,否则,返回FALSE:
StatusListEmpty(SqList*L){
if(L->len==0){
returnTRUE;
}else{
returnFALSE;
}
}
6.求线性表表长的函数:
intListLength(SqList*L){
returnL->len;
7.用e返回L中第i个元素的值
voidGetElem(SqList*L,inti,ElemType*e){
if(i<=0||i>MAXSIZE){
printf("下标越界\n\n");
*e=-1;
return;
}
if(i>L->len){
printf("超出顺序表的范围\n\n");
*e=-1;
return;
}
*e=L->data[i-1];
}
8.回L中第一个与e相同的元素位置
intLocateElem(SqList*L,ElemType*e){
inti;
intloc=0;
for(i=0;ilen;i++){
if(L->data[i]==*e){//如果找到元素了
loc=i+1;
break;
}
}
if(i==L->len){
printf("顺序表中没有找到该元素\n\n");
loc=-1;
returnloc;
}else{
returnloc;
}
}
9.如果e不是第一个元素,则返回L中e的直接前驱元素
StatusPriorElem(SqList*L,ElemType*e){
inti;
if(*e==L->data[0]){
printf("元素%d是第一个元素,没有直接前趋\n\n");
*e=-1;
returnERROR;
}
//说明e不是第一个元素
for(i=1;ilen;i++){
if(L->data[i]==*e){//说明元素的直接后继是e
*e=L->data[i-1];
printf("元素%d的直接前驱是%d\n\n",L->data[i],*e);
break;
}
}
if(i==L->len){
printf("顺序表中没有该元素\n\n");
*e=-1;
returnERROR;
}
returnOK;
}
10.如果e不是最后一个元素,则返回L中e的直接后继元素
StatusNextElem(SqList*L,ElemType*e){
inti;
//e是最后一个元素
if(*e==L->data[L->len-1]){
printf("元素%d为最后一个元素,无直接后继\n\n",*e);
returnERROR;
}
for(i=0;ilen-1;i++){
if(L->data[i]==*e){
*e=L->data[i+1];
printf("元素%d的直接后继是%d\n\n",L->data[i],*e);
break;
}
}
if(i==L->len-1){
printf("顺序表中没有元素%d\n\n",*e);
returnERROR;
}
returnOK;
}
11.在顺序表的i个位置插入元素e
StatusListInsert(SqList*L,intloc,ElemType*e){
inti;
if(loc<=0||loc>MAXSIZE){
printf("下标越界\n\n");
returnERROR;
}
if(loc>L->len+1){
printf("下标超出顺序表长度\n\n");
returnERROR;
}
if(loc==L->len){
L->data[loc-1]=*e;
L->len++;
printf("元素插入成功\n\n");
returnOK;
}
for(i=L->len;i>=loc;i--){
L->data[i]=L->data[i-1];
}
L->data[i]=*e;
L->len++;
printf("元素插入成功\n\n");
returnOK;
}
12.删除顺序表的第loc个元素,并用e返回
StatusListDlete(SqList*L,intloc,ElemType*e){
inti;
if(loc<=0||loc>MAXSIZE){
printf("下标越界\n\n");
returnERROR;
}
if(loc>L->len){
printf("下标超出顺序表长度\n\n");
returnERROR;
}
*e=L->data[loc-1];
for(i=loc;ilen;i++){
L->data[i-1]=L->data[i];
}
L->len--;
printf("删除的元素是:
%d\n\n",*e);
returnOK;
}
13.访问顺序表的第loc个元素
StatusListTraverse(SqList*L,intloc){
if(loc<=0||loc>MAXSIZE){
printf("下标越界\n\n");
returnERROR;
}
if(loc>L->len){
printf("下标超出顺序表长度\n\n");
returnERROR;
}
printf("顺序表的第%d个元素是:
%d\n\n",loc,L->data[loc-1]);
returnOK;
}
14.输出顺序表的元素
voidprint(SqList*L){
inti;
if(i<0||i>MAXSIZE){
printf("顺序表为空\n\n");
return;
}
for(i=0;ilen;i++){
printf("%d",L->data[i]);
}
printf("\n顺序表输出完毕\n\n");
}
15.最后,在main函数中调用相关的操作函数:
intmain(void){
SqList*L;
intselect,i,loc,flag;
ElemTypee=-1;
L=(SqList*)malloc(sizeof(SqList));
InitList(L);
while
(1){
options();
printf("请输入你的选择:
");
scanf("%d",&select);
if(select==12){
break;
}
switch(select){
case1:
ClearList(L);
break;
case2:
flag=ListEmpty(L);
if(flag==TRUE){
printf("顺序表为空\n\n");
}else{
printf("顺序表不为空\n\n");
}
break;
case3:
i=ListLength(L);
printf("顺序表中有%d个元素\n\n",i);
break;
case4:
printf("请输入查找的元素的位置:
");
scanf("%d",&loc);
GetElem(L,loc,&e);
if(e!
=-1){
printf("该位置的元素值是:
%d\n\n",e);
}
break;
case5:
printf("请输入要查找的元素:
");
scanf("%d",&e);
i=LocateElem(L,&e);
if(i!
=0&&i!
=-1){
printf("元素的位置为:
%d\n\n",i);
}
break;
case6:
printf("请输入元素的值:
");
scanf("%d",&e);
PriorElem(L,&e);
break;
case7:
printf("请输入元素的值:
");
scanf("%d",&e);
NextElem(L,&e);
break;
case8:
printf("请输入插入的元素的位置:
");
scanf("%d",&loc);
printf("请输入要插入的元素:
");
scanf("%d",&e);
ListInsert(L,loc,&e);
break;
case9:
printf("请输入要删除的元素的位置:
");
scanf("%d",&loc);
ListDlete(L,loc,&e);
break;
case10:
printf("请输入位置loc:
");
scanf("%d",&loc);
ListTraverse(L,loc);
break;
case11:
print(L);
break;
default:
break;
}
}
return0;
}
(二)、程序运行截图
1.编译运行上述程序:
2.输入5个数,分别为1,2,3,4,5
3.求线性表是否为空:
4.求线性表的长度:
5.输出顺序表的第4个元素:
6.输出第一次出现元素3的位置:
7.向线性表中插入一个元素:
8.删除元素4,并输出
9.输出线性表的元素:
10.在线性表的-1位置插入数据:
11.清空线性表的所有元素
五、实验总结
1.由于线性表是采用的是数组存储,因此,在第i个位置添加或删除一个元素时,需要移动n-i个位置,其时间复杂度为O(n)
2.顺序表的删除并非真正意义的删除,由于数组的特殊原因,只是显示的一种“假象”,如果采用动态的扩展空间,可以实现真正意义的释放空间
3.采用结构体时,访问成员,一般采用结构体变量名.成员变量名
4.采用结构体指针,访问变量,采用结构体变量名->成员变量名
5.编写相关的数据结构算法时,要注意下标小于0和指针指向为空或者下标越界等常见问题。
6.顺序表的插入、删除的时间复杂度是O(n),而访问某个元素的时间复杂度是O
(1),输出所有元素的时间复杂度也是O(n).