目录
目录
完成顺序表操作,要求数据元素是构造数据类型。
思维导图
头文件:goods.h
#ifndef _GOODS_H_
#define _GOODS_H_
#define MAX 40 //定义顺序表的最大容量
typedef struct
{
int year;
int month;
int day;
}datas;//存储年月日
typedef struct
{
char name[32]; //存储商品名称
char position[32]; //存储商品产地
char brand[32]; //存储商品的品牌
double price; //存储商品价格
datas DOP; //存储商品的生产日期
int EXP; //存储商品的保质期
datas updatas; //存储商品信息更新日期
datas expriation; //存储商品过期时间
}datatype; //以整形为例,数据元素类型
//定义顺序表类型的基本格式
typedef struct
{
datatype data[MAX]; //存储数据元素的数组
int len; //存储当前顺序表的长度
}seqlist,*seqlist_ptr; //重命名为一个结构体变量,和一个指针类型
//创建菜单输出函数 行5
void menue_create();
//创建一个关于要修改内容的菜单
void menue_create_ch();
//创建根据flag判断是否展示的函数 行15
void show_or_not(int flag,seqlist_ptr S);
//创建顺序表 行21
seqlist_ptr listCreate();
//判断空 行49
int listEmpty(seqlist_ptr S);
//判断满 行38
int listFULL(seqlist_ptr S);
//创建顺序表数据元素输入函数
datatype data_input();
//创建日期计算函数
datas data_caculate(datas e,int day);
//向顺序表中添加元素
int listAdd(seqlist_ptr S,datatype e);
//遍历顺序表
void listShow(seqlist_ptr S);
//元素输出函数
void data_output(datatype e);
//任意位置插入元素
int listInsertByPos(seqlist_ptr S,int pos,datatype e);
//任意位置删除元素
int listDeletPos(seqlist_ptr S,int pos);
//按位置进行修改
int listUpdataPos(seqlist_ptr S,int pos, datatype e);
//按值进行修改
int listUpdataValue(seqlist_ptr S,datatype old_e,datatype new_e);
//查找指定位置的元素
datatype *listSearchByPos(seqlist_ptr S,int pos);
//按值进行查找元素返回元素的位置
int listSearchByValue(seqlist_ptr S,datatype e);
//将顺序表排序(使用选择排序,传一个flag,1升0降)
void listSort(seqlist_ptr S,int flag);
//将顺序表去重
void listUnique(seqlist_ptr S);
//求最值操作
int listMoValue(seqlist_ptr S,int flag);
//最值元素输出
void most_output(seqlist_ptr S,int flag);
//顺序表反转
void listReverse(seqlist_ptr S);
//顺序表释放
void listFree(seqlist_ptr S);
#endif
源文件:goods.c
#include"goods.h"
#include
#include
#include
//创建菜单输出函数
void menue_create(){
printf("***************************************************\n");
printf("请输入您的需求:\n");
printf("0.退出系统\n");
printf("1.继续向表中添加元素\n");
printf("2.按名字查询该商品的过期时间\n");
printf("3.将商品所有信息移除(按商品名查询)\n");
printf("4.商品信息修改\n");
printf("5.展示已有所有商品信息\n");
printf("6.在一个商品后插入新商品信息\n");
printf("7.输出最贵或者最便宜的商品的信息\n");
printf("8.输入要将所有商品按价格升序排列(1)还是降序排列(0)\n");
}
//创建一个关于要修改内容的菜单
void menue_create_ch(){
printf("0.取消\n");
printf("1.修改商品名称\n");
printf("2.修改商品产地\n");
printf("3.修改商品的品牌\n");
printf("4.修改商品价格\n");
printf("5.修改商品生产日期\n");
printf("6.修改商品保质期\n");
}
//创建根据flag判断是否展示的函数
void show_or_not(int flag,seqlist_ptr S){
if(flag){
listShow(S);
}
}
//创建顺序表
seqlist_ptr listCreate(){
//在堆区申请一个顺序表的空间大小
seqlist_ptr S = (seqlist_ptr)malloc(sizeof(seqlist));
//判断是否申请成功
if(NULL == S){
printf("顺序表创建失败\n");
return NULL;
}
//此时顺序表已经创建成功
memset(S->data,0,sizeof(S->data)); //清空数组
S->len = 0; //数组长度清零
printf("顺序表创建成功\n");
return S;
}
//判满,成功返回真,失败返回假
int listFULL(seqlist_ptr S){
//判断逻辑
if(NULL == S){
printf("所给顺序表不合法\n");
return 0;
}
//合法,则返回是否已经满了
return S->len == MAX;
}
//判空,如果空返回真,非空返回假
int listEmpty(seqlist_ptr S){
//判断逻辑
if(NULL == S){
printf("所给顺序表不合法\n");
return 0;
}
//合法返回是否空
return S->len == 0;
}
//创建顺序表数据元素输入函数
datatype data_input(){
datatype e;
printf("请输入商品的名称:");
scanf("%s",e.name);
printf("请输入商品的产地:");
scanf(" %s",e.position);
printf("请输入商品的品牌:");
scanf(" %s",e.brand);
printf("请输入商品的价格:");
scanf("%lf",&e.price);
while(1){
printf("请输入商品的生产日期(年 月 日):");
scanf("%d%d%d",&e.DOP.year,&e.DOP.month,&e.DOP.day);
printf("请输入商品的保质期(天):");
scanf("%d",&e.EXP);
printf("请输入今天的日期(年 月 日):");
scanf("%d%d%d",&e.updatas.year,&e.updatas.month,&e.updatas.day);
if(e.DOP.year<=e.updatas.year&&e.DOP.month>0&& e.DOP.month<=12&&\
e.DOP.day>0&& e.DOP.day<32&&\
e.updatas.month>=0&& e.updatas.month<=12&& e.updatas.day>0&&\
e.updatas.day<32){//只有输入正确才能跳出死循环
if(e.DOP.year==e.updatas.year){//生产日期的年份如果等于今日,判断月份是否合理
if(e.DOP.month==e.updatas.month&&e.DOP.day<=e.updatas.day){
break;
}
if(e.DOP.monthdata[S->len] = e;//将新元素放入最后一个位置
//表的变化
S->len++;
printf("添加成功\n");
return 1;
}
//遍历顺序表
void listShow(seqlist_ptr S){
//判断逻辑
if(NULL == S||listEmpty(S)){
printf("遍历失败\n");
return; //会报警告
}
//遍历顺序表
printf("当前顺序表的元素分别是:\n");
int i = 0;
for(i=0; ilen; i++){
data_output(S->data[i]);
printf("*********************************************\n");
}
putchar(10);
}
//元素输出函数
void data_output(datatype e){
printf("******************************************\n");
printf("商品的名称:%s\n",e.name);
printf("商品的产地:%s\n",e.position);
printf("商品的品牌:%s\n",e.brand);
printf("商品的价格:%.2f\n",e.price);
printf("商品的生产日期:%d年%d月%d日\n",e.DOP.year,e.DOP.month,e.DOP.day);
printf("商品的保质期(天):%d\n",e.EXP);
printf("商品信息更新的日期:%d年%d月%d日\n",e.updatas.year,e.updatas.month,e.updatas.day);
printf("商品过期的日期:%d年%d月%d日\n",e.expriation.year,e.expriation.month,e.expriation.day);
}
//创建日期计算函数
datas data_caculate(datas e,int day){
int flag = 0;//定义一个标志位,记录润平年
int i = 0;
for(i=0; iS->len){
printf("插入失败\n");
return 0;
}
//腾空过程
int i = 0;
for(i=S->len-1; i>=pos; i--){
S->data[i+1] = S->data[i]; //将当前元素后移
}
//插入逻辑
S->data[pos] = e; //将新元素放入要插入的位置
//表的变化
S->len++;
printf("插入成功\n");
// listShow(S);
return 1;
}
//任意位置删除元素
int listDeletPos(seqlist_ptr S,int pos){
//判断逻辑
if(NULL == S||listEmpty(S)||pos<0||pos>S->len){
printf("删除失败\n");
return 0; //会报警告
}
//删除过程
int i = 0;
for(i=pos+1; ilen; i++){
S->data[i-1] = S->data[i]; //将当前元素后移
}
//表的变化
S->len--;
printf("删除成功\n");
// listShow(S);
return 1;
}
#if 0
//按位置进行修改
int listUpdataPos(seqlist_ptr S,int pos, datatype e){
//判断逻辑
if(NULL == S||listEmpty(S)||pos<0||pos>S->len){
printf("修改失败\n");
return 0;
}
//更新逻辑
S->data[pos] = e;
printf("更新成功\n");
return 1;
}
//查找指定位置的元素
datatype *listSearchByPos(seqlist_ptr S,int pos){
//判断逻辑
if(NULL == S||listEmpty(S)||pos<0||pos>=S->len){
printf("查找失败\n");
return NULL;
}
//可以进行找到并返回
return &S->data[pos];
}
#endif
//按值进行查找元素返回元素的位置
int listSearchByValue(seqlist_ptr S,datatype e){
//判断逻辑
if(NULL == S || listEmpty(S)){
printf("查找失败\n");
return -1;
}
//遍历顺序表对比是否有与要找的元素相同的元素
for(int i=0; ilen; i++){
if(!strcmp(e.name,S->data[i].name)){
return i; //找到就直接返回下标
}
}
/*printf("没有找到\n");*/
return -1; //如果整个for循环都执行完了,还没有跳出,说明遍历顺序表也没能找到要找的元素
//返回-1,表示没找到。
}
#if 0
//按值进行修改
int listUpdataValue(seqlist_ptr S,datatype old_e,datatype new_e){
//判断逻辑
if(NULL == S || listEmpty(S) || old_e == new_e){
printf("修改失败\n");
return 0;
}
//可以进行修改,并且全部修改
int index = 0;
while((index = listSearchByValue(S,old_e)) >=0 ){
//调用按位置进行修改函数
listUpdataPos(S,index,new_e);
}
printf("修改成功\n");
return 1;
}
#endif
//将顺序表排序(使用选择排序,传一个flag,1升0降)
void listSort(seqlist_ptr S,int flag){
//判断逻辑
if(NULL == S){
printf("所给顺序表不合法\n");
return;
}
//选择排序
int i = 0;
int j = 0;
int index = 0;//定义记录下标的变量
datatype tmp;//定义交换的中间变量
for(i=1; ilen; i++){ //控制交换的趟数
index = 0;
if(1 == flag){ //如果flag是1,表示升序排列
for(j=0; j<=S->len-i; j++){ //一直要比到data中的最后一个元素,即下表为len-1的元素,
//之后每次都可以少比较1个元素,但由于i是从1开始的,所以判断条件为<=len-i
if(S->data[index].pricedata[j].price){
index = j;//如果遍历到的元素比index对应的元素还大,就把更大的值的下标赋给index,以找到最大值的下标
}
}
if(index!=S->len-i){ //将得到的最大值,和最后一个元素交换位置,第二大的和倒数第二个
//元素交换位置,以此类推
tmp = S->data[index];
S->data[index] = S->data[S->len-i];
S->data[S->len-i] = tmp;
}
}else{//降序排列
for(j=0; j<=S->len-i; j++){ //一直要比到data中的最后一个元素,即下表为len-1的元素,
//之后每次都可以少比较1个元素,但由于i是从1开始的,所以判断条件为<=len-i
if(S->data[index].price>S->data[j].price){
index = j;//如果遍历到的元素比index对应的元素还小,就把更小的值的下标赋给index,以找到最小值的下标
}
}
if(index!=S->len-i){ //将得到的最小值,和最后一个元素交换位置,第二小的和倒数第二个
//元素交换位置,以此类推
tmp = S->data[index];
S->data[index] = S->data[S->len-i];
S->data[S->len-i] = tmp;
}
}
}
}
#if 0
//将顺序表去重
void listUnique(seqlist_ptr S){
//判断逻辑
if(NULL == S || S->len <= 1){
printf("进入失败\n");
return;
}
//去重逻辑
int i = 0;
int j = 0;
for(i=0; ilen; i++){
//将当前元素后面的所有元素遍历一遍
for(j=i+1; jlen; j++){
if(S->data[i] == S->data[j]){
//删除j这个元素
listDeletPos(S,j);
j--; //防止漏删
}
}
}
printf("去重成功\n");
}
#endif
//求最值操作
int listMoValue(seqlist_ptr S,int flag){
/* //判断逻辑
if(NULL == S){
printf("所给顺序表不合法\n");
return 0;
}
*/
//求最值
int pos = 0;
double value = S->data[0].price; //定义一个变量保存最值
int i = 0;
for(i=0; ilen; i++){
if(1 == flag){ //如果flag为1说明要求最大值,否则为最小值
if(value< S->data[i].price){
value = S->data[i].price;
pos = i;
}
}else{
if(value> S->data[i].price){
value = S->data[i].price;
pos = i;
}
}
}
return pos;
}
//最值元素输出
void most_output(seqlist_ptr S,int flag){
//判断逻辑
if(NULL == S|| S->len==0){
printf("最值查找失败\n");
return ;
}
if(1 == flag){
printf("最贵的商品信息为:\n");
}else{
printf("最便宜的商品信息为:\n");
}
int pos = 0;
pos = listMoValue(S,flag);
int i = 0;
for(i=0; ilen; i++){
if(S->data[i].price==S->data[pos].price){
data_output(S->data[i]);
}
}
}
#if 0
//顺序表反转
void listReverse(seqlist_ptr S){
//判断逻辑
if(NULL == S){
printf("所给顺序表不合法\n");
return;
}
int i = 0;
datatype tmp = 0;//定义一个中间变量
for(i=0; ilen/2; i++){ //交换次数为len/2次,比如,有4个元素,那么len正好等于4,交换2次,3个元素交换1次,3/2也是1
tmp = S->data[i];
S->data[i] = S->data[S->len-1-i];
S->data[S->len-1-i] = tmp;
}
}
#endif
//顺序表释放
void listFree(seqlist_ptr S){
if(NULL != S){
free(S);
S = NULL;
}
}
测试文件:main.c
#include"goods.h"
#include
int main(int argc, const char *argv[])
{
seqlist_ptr S = listCreate();//调用顺序表调用函数
if(NULL == S){
printf("顺序表创建失败\n");
return 0;
} //只有顺序表创建成功才能进入后续步骤
int choice = 0;
datatype e;
int pos;
int flag = 0;
while(1){
menue_create();
scanf("%d",&choice);
switch(choice){
case 0:
goto LOOP;
break;
case 1:
printf("请输入要添加的元素内容:\n");
e = data_input();//调用输入函数,获取数据
flag=listAdd(S,e);//调用添加元素函数
//show_or_not(flag,S);//根据上一步的返回值决定要不要输出
break;
case 2:
printf("请输入要查询的商品名:");
scanf("%s",e.name);
pos = listSearchByValue(S,e);//根据商品名获取商品信息的位置
if(-1==pos){
printf("不存在该商品\n");
continue;
}else{
printf("其过期日期为:%d年%d月%d日\n",S->data[pos].expriation.year,S->data[pos].expriation.month,S->data[pos].expriation.day);
}
break;
case 3:
printf("请输入要删除的商品名:");
scanf("%s",e.name);
pos = listSearchByValue(S,e);//根据商品名获取其信息在顺序表中的位置
if(-1==pos){
printf("商品本就不存在\n");
continue;
}else{
flag=listDeletPos(S,pos);//调用按位置删除函数
printf("删除成功\n");
//show_or_not(flag,S); //根据函数返回值决定是否输出结果
}
break;
case 4:
printf("请输入要修改的商品名:");
scanf("%s",e.name);
pos = listSearchByValue(S,e);//获取商品信息信息在顺序表中位置
printf("请输入今天的日期(年 月 日):");
scanf("%d%d%d",&e.updatas.year,&e.updatas.month,&e.updatas.day);
printf("请输入要修改的内容:\n");
menue_create_ch();
int choice4;
scanf("%d",&choice4);
switch(choice4){
case 0:
printf("并未进行修改\n");
break;
case 1:
printf("修改前商品的名字为:%s\n",S->data[pos].name);
printf("请输入修改后的商品名字:");
scanf("%s",S->data[pos].name);
printf("修改后商品的名字为:%s\n",S->data[pos].name);
break;
case 2:
printf("修改前商品的产地为:%s\n",S->data[pos].position);
printf("请输入修改后的商品产地:");
scanf("%s",S->data[pos].name);
printf("修改后商品的产地为:%s\n",S->data[pos].position);
break;
case 3:
printf("修改前商品的品牌为:%s\n",S->data[pos].brand);
printf("请输入修改后的商品品牌:");
scanf("%s",S->data[pos].brand);
printf("修改后商品的品牌为:%s\n",S->data[pos].brand);
break;
case 4:
printf("修改前商品的价格为:%.2f\n",S->data[pos].price);
printf("请输入修改后的商品价格:");
scanf("%lf",&S->data[pos].price);
printf("修改后商品的价格为:%.2f\n",S->data[pos].price);
break;
case 5:
printf("修改前商品的生产日期:%d年%d月%d日\n",S->data[pos].DOP.year,S->data[pos].DOP.month,S->data[pos].DOP.day);
printf("修改前商品过期的日期:%d年%d月%d日\n",S->data[pos].expriation.year,S->data[pos].expriation.month,S->data[pos].expriation.day);
while(1){
printf("要将商品的生产日期(年 月 日)改为:");
scanf("%d%d%d",&e.DOP.year,&e.DOP.month,&e.DOP.day);
if(S->data[pos].DOP.year<=S->data[pos].updatas.year&&S->data[pos].DOP.month>0&& S->data[pos].DOP.month<=12&&\
S->data[pos].DOP.day>0&& S->data[pos].DOP.day<32&&\
S->data[pos].updatas.month>=0&& S->data[pos].updatas.month<=12&& S->data[pos].updatas.day>0&&\
S->data[pos].updatas.day<32){//只有输入正确才能跳出死循环
if(S->data[pos].DOP.year==S->data[pos].updatas.year){//生产日期的年份如果等于今日,判断月份是否合理
if(S->data[pos].DOP.month==S->data[pos].updatas.month&&S->data[pos].DOP.day<=S->data[pos].updatas.day){
break;
}
if(S->data[pos].DOP.monthdata[pos].updatas.month){
break;
}
}else{
break;
}
}
printf("输入有误,请重新输入\n");
}
e.expriation = data_caculate(S->data[pos].DOP,S->data[pos].EXP);
printf("输入成功\n");
printf("修改后商品的生产日期:%d年%d月%d日\n",S->data[pos].DOP.year,S->data[pos].DOP.month,S->data[pos].DOP.day);
printf("修改后商品过期的日期:%d年%d月%d日\n",S->data[pos].expriation.year,S->data[pos].expriation.month,S->data[pos].expriation.day);
break;
case 6:
printf("修改前商品的保质期(天):%d\n",S->data[pos].EXP);
printf("修改后商品过期的日期:%d年%d月%d日\n",S->data[pos].expriation.year,S->data[pos].expriation.month,S->data[pos].expriation.day);
printf("请输入要将商品的保质期修改为(天):");
scanf("%d",&S->data[pos].EXP);
e.expriation = data_caculate(S->data[pos].DOP,S->data[pos].EXP);
printf("修改后商品的保质期(天):%d\n",S->data[pos].EXP);
printf("修改后商品过期的日期:%d年%d月%d日\n",S->data[pos].expriation.year,S->data[pos].expriation.month,S->data[pos].expriation.day);
break;
default:
printf("输入不规范,亲人两行泪,请重新输入\n");
break;
}
printf("修改后该商品的信息为\n");
data_output(S->data[pos]);
break;
case 5:
listShow(S);
break;
case 6:
printf("请输入想要在那个商品后插入新商品:\n");
scanf("%s",e.name);
pos = listSearchByValue(S,e);//根据商品名获取其信息在顺序表中的位置
if(-1==pos){
printf("商品不存在\n");
continue;
}else{
printf("请输入要插入的商品信息:\n");
e = data_input();
flag=listInsertByPos(S,pos,e);//调用按位置删除函数
printf("插入成功\n");
//show_or_not(flag,S); //根据函数返回值决定是否输出结果
}
break;
case 7:
while(1){
printf("请输入要找最贵的还是最便宜的(1求最贵,0求便宜):");
scanf("%d",&flag);
if(1==flag||0==flag){
break;
}
printf("输入不规范,亲人两行泪,请重新输入\n");
}
most_output(S,flag);
break;
case 8:
while(1){
printf("请输入升序排列的还是降序排列的(1升,0奖):");
scanf("%d",&flag);
if(1==flag||0==flag){
break;
}
printf("输入不规范,亲人两行泪,请重新输入\n");
}
listSort(S,flag);
break;
default:
printf("输入不规范,亲人两行泪,请重新输入\n");
break;
}
}
LOOP:
printf("感谢使用,再见\n");
listFree(S);//释放空间
S = NULL;
return 0;
}
主菜单:
添加商品信息的操作:
日期输入错误的反馈:
查询商品过期时间:
展示已录入所有商品的所有信息:
修改某商品的信息:
将所有商品按价格进行升序排列并展示:
输出最贵商品信息:
将修改某一商品价格,使表中出现两个价格相同且同样是最贵的,输出最贵商品信息:
删除某一商品所有信息,并展示:
退出系统: