实验一 顺序表基本操作的实现
一、实验学时: 2学时
二、实验目的
- 实现顺序表的基本操作
三、实验内容
- 顺序表的建立、取指定元素、返回指定元素位置
- 顺序表中插入新元素、删除指定元素操作的实现
四、主要仪器设备及耗材
- 硬件:计算机一台
- 软件:VC++ 6.0,MSDN2003或者以上版本
五、实验步骤
- 分析问题
- 写出算法
- 编制程序
- 上机调试
- 分析结果
六、程序清单
#include<stdio.h>
#include<string.h>
#include<stdlib.h> //要用exit所以加它
#define OK 1 //成功返回值
#define ERROR 0 //出错返回值
#define OVERFLOW -2 //溢出返回值
#define MAXSIZE 10000 //空间大小
//用户自定义类型Status
typedef int Status;
//定义图书结构体
typedef struct
{
char no[20]; //书号
char name[50]; //书名
float price; //价格
}Book;
//用户自定义类型SqList
typedef struct
{
Book *elem; //图书指针
int length; //图书顺序表长度
}SqList;
//初始化顺序表
Status InitList(SqList &L) //形参要的是SqList的引用,调用时是InitList(L),因为引用更改后它本身就更改了。不然传的只是副本,对原值无影响。
{
L.elem=new Book[MAXSIZE]; //为顺序表分配一个MAXSIZE大小的数组空间
if(!L.elem) exit(OVERFLOW); //分配失败退出
L.length=0; //空表长度为0
return OK;
}
//取值
Book GetElem(SqList L,int i) //取出顺序表位于第i个位置的元素
{
if(i<1||i>L.length) printf("取值操作异常"); //取值异常
return L.elem[i-1]; //返回找到的值
}
//查找
int LocateElem(SqList L,Book e) //查找元素e在顺序表中的位置
{
int i;
for(i=0;i<L.length;i++)
if(strcmp(L.elem[i].no,e.no)==0&&strcmp(L.elem[i].name,e.name)==0&&L.elem[i].price==e.price) return i+1;
return 0;
}
//插入
Status ListInsert(SqList &L,int i,Book e) //将元素e插入到顺序表L的第i的位置
{
if((i<1)||(i>L.length+1)) return ERROR;
if(L.length==MAXSIZE) return ERROR;
int j;
for(j=L.length-1;j>=i-1;j--)
L.elem[j+1]=L.elem[j]; //i位置及以后的元素整体后移
L.elem[i-1]=e;
++L.length;
return OK;
}
//删除
SqList ListDelete(SqList &L,int i)
{
if((i<1)||(i>L.length+1)) printf("删除异常");
int j;
for(j=i;j<=L.length-1;j++)
L.elem[j-1]=L.elem[j]; //被删元素后面的整体前移
--L.length;
return L;
}
int main()
{
SqList L;
Status status = InitList(L);
if(!status)
{
printf("顺序表初始化失败!\n");
return ERROR;
}
else
{
printf("顺序表初始化成功!\n");
Book e;
printf("请录入图书信息:\n");
printf("书号:");scanf("%s",&e.no);
printf("书名:");scanf("%s",&e.name);
printf("价格:");scanf("%f",&e.price);
int i;
for(i=1;;++i)
{
ListInsert(L,i,e);
printf("成功收藏%d本书至图书馆\n",i);
printf("书号:");scanf("%s",&e.no);
printf("书名:");scanf("%s",&e.name);
printf("价格:");scanf("%f",&e.price);
if(e.price==0)
break;
}
printf("图书馆共%d本书\n",L.length);
printf("图书馆的图书列表:\n");
Book e1;
int j;
printf("编号\t书名\t\t价格\n");
for(j=1;j<=L.length;j++)
{
e1=GetElem(L,j);
printf("%s\t",e1.no);
printf("%s\t",e1.name);
printf("%-7.2f\n",e1.price);
}
Book e2={"10102","计算机组成原理",46.5};
int location = LocateElem(L,e2);
printf("其中第%s在第%d个位置\n",e2.name,location);
printf("------------------------------\n");
printf("删除第二本后的列表:\n");
SqList sl = ListDelete(L,2);
printf("图书馆共%d本书\n",sl.length);
printf("图书馆的图书列表:\n");
printf("编号\t书名\t\t价格\n");
for(j=1;j<=sl.length;j++)
{
e2=GetElem(sl,j);
printf("%s\t",e2.no);
printf("%s\t",e2.name);
printf("%-7.2f\n",e2.price);
}
}
}
七、运行结果及分析
八、小总结
- 建立顺序表(初始化):初始化就是用指针指向新分配的空间,若内存不足分配失败则退出,否的话长度置为0,然后返回OK。
- 取指定位置元素(取值):就是超出范围取值异常,在范围内就返回第i个元素。
- 返回指定元素位置(查找):循环查找,如果是基本数据类型相等就行了,像本程序中用的是Book结构体类型,所以要比较每一个数据,都相等则返回位置。
- 向指定位置插入元素(插入):超出范围和溢出都报错,i位置及以后的元素整体后移空出位置i放元素e,然后长度加1。
- 删除指定位置元素(删除):超出范围报错,否则被删元素后面的元素整体前移,长度减1。
- 要说的问题:&L与L
参数里的这两者区别,带&是传的引用,可以更改L里的数据,不然的话只是传了一个副本,形参改变对实参无影响。