请实现购物车系统,把商品【商品名称,商品属性、价格,个数】信息存储到顺序表中,请完成一下操作操作
结构体定义
typedef struct{
char name[20];//名称
char arrriture[20];//属性float price;//价格
int num; //个数}Goods;
typedef struct{
Goods data[MAXSIZE];int len;
}seqlist;
1,在堆区申请空间
2,实现顺序表数据元素在表尾录入
3,实现顺序表输出
4,实现顺序表按下标插入商品信息
5,实现顺序表按下标删除商品信息
6,查找商品名称key是否在购物车信息中出现
7,修改商品名称key的购买数量,修改为n
8,删除最贵的商品信息
9,对商品总价实现升序排序
10,如果有两个商品名称相同的商品信息,则去重
11,释放堆区空间
代码说明:
①此题默认商品名称相同<===>商品的属性和价格都相同
②在顺序表表尾输入和顺序表按下标插入的功能中,每次插入之前,先判断是否存在相同的商品名称,不存在则正常插入,存在,则将待插入元素中的数量加到已存在的商品数量中,实现累加,同时避免重复元素产生
③由②可以得出,插入的元素不会出现重复,所以将去重的功能放置最开始,以防顺序表初始化时自带重复
④去重功能说明:将删除的元素的数量累加到相同商品名的元素中的数量上面
⑤此题为极简系统,注意使用方法
⑥系统功能稍多,验证过于复杂,仅取一小部分作为例子,源码在下面,可以自行验证
//head.h
#ifndef __HEAD_H__
#define __HEAD_H__
#include
#include
#include
#define Maxsize 200
typedef struct
{
char name[20];//名称
char arriture[20];//商品属性
int price;//价格
int num;//数量
}Goods;
typedef struct{
Goods data[Maxsize];
int len;
}Seqlist;
int isEmpty(Seqlist *res);
int isFull(Seqlist *res);
Seqlist *SeqlistCreate();
int InsertRear(Seqlist *res);
void SeqlistShow(Seqlist *res);
int InsertByPos(Seqlist *res);
int DeleteByPos(Seqlist *res);
int DeleteByPos2(Seqlist *res,int pos);
int Search(Seqlist *res,char *key);
void ChangeByName(Seqlist *res,char *key,int sum);
int DeleteMostExpensive(Seqlist *res);
void sort(Seqlist *res);
void RmSame(Seqlist *res);
#endif
//test.c
#include "head.h"
//判空
int isEmpty(Seqlist *res)
{
if(res->len==0)
return 1;
return 0;
}
//判满
int isFull(Seqlist *res)
{
if(res->len==Maxsize)
return 1;
return 0;
}
//空间申请
Seqlist *SeqlistCreate()
{
Seqlist *res = (Seqlist *)malloc(sizeof(Seqlist));
if(res==NULL)
return NULL;
res->len = 0;
return res;
}
//表尾插入 空间满-1 插入成功返回0
int InsertRear(Seqlist *res)
{
if(isFull(res))
return -1;
Goods goods;
printf("请输入待添加的商品名称:");
scanf("%s",goods.name);
printf("请输入待添加的商品属性:");
scanf("%s",goods.arriture);
printf("请输入待添加的商品价格:");
scanf("%d",&goods.price);
printf("请输入待添加的商品数量:");
scanf("%d",&goods.num);
int flag = Search(res,goods.name);
if(flag==-1){//没有重复的
res->data[res->len++] = goods;
}
else
{
ChangeByName(res,goods.name,goods.num+res->data[flag].num);
}
return 0;
}
//输出
void SeqlistShow(Seqlist *res)
{
for(int i=0;i<res->len;i++){
printf("第%d项的商品名称为:%s,属性为:%s,价格为:%d,数量为:%d\n",i+1,res->data[i].name,res->data[i].arriture,res->data[i].price,res->data[i].num);
}
}
//按下标插入商品信息
int InsertByPos(Seqlist *res)
{
if(isFull(res))
return -1;
Goods goods;
printf("请输入待添加的商品名称:");
scanf("%s",goods.name);
printf("请输入待添加的商品属性:");
scanf("%s",goods.arriture);
printf("请输入待添加的商品价格:");
scanf("%d",&goods.price);
printf("请输入待添加的商品数量:");
scanf("%d",&goods.num);
int flag = Search(res,goods.name);
if(flag==-1){
int pos;
printf("请输入插入的下标位置:");
scanf("%d",&pos);
if(pos<0||pos>res->len)
return -1;
for(int i=res->len-1;i>=pos;i--){
res->data[i+1]=res->data[i];
}
res->data[pos] = goods;
res->len++;
}
else{
ChangeByName(res,goods.name,goods.num+res->data[flag].num);
}
return 0;
}
//顺序表按下标删除信息
int DeleteByPos(Seqlist *res)
{
if(isEmpty(res))
return -1;
int pos;
printf("请输入待删除的下标位置:");
scanf("%d",&pos);
if(pos<0||pos>res->len-1)
return -1;
for(int i=pos;i<res->len-1;i++){
res->data[i] = res->data[i+1];
}
res->len--;
return 0;
}
//顺序表按下标删除信息
int DeleteByPos2(Seqlist *res,int pos)
{
if(isEmpty(res))
return -1;
if(pos<0||pos>res->len-1)
return -1;
for(int i=pos;i<res->len-1;i++){
res->data[i] = res->data[i+1];
}
res->len--;
return 0;
}
//查找商品在购物车上否出现 下标或者-1
int Search(Seqlist *res,char *key)
{
if(isEmpty(res))
return -1;
for(int i=0;i<res->len;i++){
if(strcmp(res->data[i].name,key)==0)
return i;
}
return -1;
}
//查找到了==》修改商品名称key的购买数量
void ChangeByName(Seqlist *res,char *key,int sum)
{
int pos = Search(res,key);
res->data[pos].num = sum;
}
//删除最贵商品
int DeleteMostExpensive(Seqlist *res)
{
if(isEmpty(res))
return -1;
int mostExpensive;
int pos;
for(int i=0;i<res->len;i++){
if(i==0){
mostExpensive = res->data[i].price;
pos = i;
}
if(mostExpensive<res->data[i].price){
mostExpensive = res->data[i].price;
pos = i;
}
}
for(int i=pos;i<res->len-1;i++){
res->data[i] = res->data[i+1];
}
res->len--;
return 0;
}
//商品总价升序排序
void sort(Seqlist *res)
{
int cnt;
Goods temp;
for(int i=0;i<res->len;i++){
cnt = 0;
for(int j=0;j<res->len-i-1;j++){
if(res->data[j].num*res->data[j].price>res->data[j+1].num*res->data[j+1].price){
temp = res->data[j];
res->data[j] = res->data[j+1];
res->data[j+1] = temp;
cnt++;
}
}
if(cnt==0)
break;
}
}
//去重
void RmSame(Seqlist *res)
{
for(int i=0;i<res->len;i++){
for(int j=i+1;j<res->len;j++){
if(strcmp(res->data[i].name,res->data[j].name)==0){
res->data[i].num+=res->data[j].num;
DeleteByPos2(res,j);
j--;
}
}
}
}
//mian.c
#include "head.h"
int main(int argc, const char *argv[])
{
Seqlist *res = SeqlistCreate();
while(1){
printf("====================\n");
printf("1.商品信息表尾录入\n");
printf("2.商品信息打印\n");
printf("3.商品信息按下标插入\n");
printf("4.商品信息按下标删除\n");
printf("5.商品信息按名字查找\n");
printf("6.商品信息按名字修改数量\n");
printf("7.删除最贵商品信息\n");
printf("8.商品信息按价格升序排序\n");
printf("9.商品信息按名字去重\n");
printf("10.退出系统\n");
printf("====================\n");
int num;
printf("请输入序号:");
scanf("%d",&num);
if(num==10)
break;
switch(num){
case 1:{int flag = InsertRear(res);
if(flag==-1)
printf("表尾插入失败!\n");
else
printf("插入成功!\n");
break;
}
case 2:SeqlistShow(res);break;
case 3:{int flag = InsertByPos(res);
if(flag==-1)
printf("按下标插入失败!\n");
else
printf("按下标插入成功!\n");
}
break;
case 4:DeleteByPos(res);break;
case 5:{
char key[20];
printf("请输入商品名字:");
scanf("%s",key);
int flag = Search(res,key);
if(flag == -1)
printf("查找失败!\n");
else
printf("商品下标为:%d\n",flag);
break;
}
case 6:{
char key[20];
int a;
printf("请输入商品名字:");
scanf("%s",key);
printf("请输入购买数量:");
scanf("%d",&a);
int flag = Search(res,key);
if(flag == -1)
printf("没有找到,修改失败!\n");
else
ChangeByName(res,key,a);
break;
}
case 7:{int flag = DeleteMostExpensive(res);
if(flag==-1)
printf("最贵商品信息删除失败!\n");
else
printf("最贵商品信息删除成功!\n");
break;
}
case 8:sort(res);SeqlistShow(res);break;
case 9:RmSame(res);SeqlistShow(res);break;
default :printf("序号格式错误,请重新输入!\n");break;
}
}
free(res);
res = NULL;
return 0;
}
链表中存储数据类型为字符串,请完成以下功能
1.在堆区申请空间
⒉.实现头插、头删、尾插、尾删
3,遍历链表
4,在任意位置插入
5,任意位置删除
6,按元素修改
7,按元素查找
8,单向链表逆置
9,链表降序排序
10,释放链表空间
说明: 每个函数测试过于繁琐,可以复制代码自行测试
//head.h
#ifndef __HEAD_H__
#define __HEAD_H__
#include
#include
#include
typedef char datatype[20];//字符串
typedef struct node
{
union{
int len;
datatype data;
};
struct node *next;
}*Linklist,Node;
void LinklistSort(Linklist L);
void LinklistRev(Linklist L);
int UpdataByPos(Linklist L,int pos,datatype e);
void SearchByPos(Linklist L,int pos);
int DeleteByPos(Linklist L,int pos);
int InsertByPos(Linklist L,int pos,datatype e);
void DeleteHead(Linklist L);
Linklist LinklistCreateHead();
void InsertRear(Linklist L,datatype e);
void LinklistShow(Linklist L);
void InsertHead(Linklist L,datatype e);
Linklist LinklistCreateNode();
void DeleteRear(Linklist L);
int DeleteByData(Linklist L,datatype e);
Linklist SearchByData(Linklist L,datatype key);
int UpdataByData(Linklist L,datatype e,datatype key);
void LinklistFree(Linklist L);
#endif
//test.c
#include "head.h"
//头结点申请空间
Linklist LinklistCreateHead()
{
Linklist L=(Linklist)malloc(sizeof(Node));
if(L==NULL)
return NULL;
//节点创建成功
L->len=0; //链表长度为0,链表为空
L->next=NULL;//链表指针域为空
return L;
}
//普通结点申请
Linklist LinklistCreateNode()
{
Linklist p=(Linklist)malloc(sizeof(Node));
if(p==NULL)
return NULL;
//创建成功
strcpy(p->data,""); //表示创建新节点的数据域清0
p->next=NULL;//表示创建新节点指针域为空
return p;
}
//头插法
void InsertHead(Linklist L,datatype e)
{
//1,创建新结点
Linklist p=LinklistCreateNode();
if(p==NULL)
return;
//节点创建成功
strcpy(p->data,e);
p->next=L->next;
L->next=p;
L->len++;
}
//单向链表尾插
void InsertRear(Linklist L,datatype e)
{
//先创建一个新节点
Linklist p=LinklistCreateNode();
if(p==NULL)
return;
//找到最后一个节点
Linklist q=L;
while(q->next!=NULL)
{
q=q->next;
}
//把新节点插入到最后一个节点的后面
strcpy(p->data,e);
q->next=p;
L->len++;
}
//遍历链表
void LinklistShow(Linklist L)
{
while(L->next)//while(p->next!=NULL)
{
L=L->next;
printf("%s\n",L->data);
}
}
//头删:永远删除头节点的后继节点
//无返回值函数
void DeleteHead(Linklist L)
{
//1,判段链表是否为空
if(L->len==0)
return;
//2,删除
Linklist p=L->next;
L->next=p->next;
free(p);
p=NULL;
L->len--;
}
//尾删:永远只删除最后一个节点
void DeleteRear(Linklist L)
{
//1,判空
if(L->len==0)
return;
//2.需要找到最后一个节点的直接前去节点
Linklist p=L;
for(int i=0;i<L->len-1;i++)
{
p=p->next;
}
//直接释放p的后继节点/最后一个节点
free(p->next);
p->next=NULL;
L->len--;
}
//链表按位置插入
//插入失败返回-1 成功返回0
int InsertByPos(Linklist L,int pos,datatype e)
{
//1,判断链表是否为空
//2.判断位置是是否合法
if(L==NULL || pos<1 || pos>L->len+1)
{
printf("插入失败\n");
return -1;
}
//3,找到pos-1位置,起名字p
Linklist p=L;//p从头节点开始向后遍历
for(int i=0;i<pos-1;i++)
{
p=p->next;//向后移动
}
//4,在p和p->next之间插入新节点s
Linklist s=LinklistCreateNode();
if(s==NULL)
{
printf("新节点创建失败\n");
return -1;
}
//s的数据域
strcpy(s->data,e);
//s的指针域
s->next=p->next;
p->next=s;
L->len++;
return 0;
}
//链表按位置删除
//成功返回0 失败返回-1
int DeleteByPos(Linklist L,int pos)
{
//1,判空
//2.判断位置是是否合法
if(L->len==0 || pos<1 || pos>L->len)
{
printf("删除失败\n");
return -1;
}
//3,找到pos-1位置起名p
Linklist p=L;
for(int i=0;i<pos-1;i++)
{
p=p->next;
}
//4,删除p->next
Linklist q=p->next;
p->next=q->next;
free(q);
q=NULL;
L->len--;
return 0;
}
//链表按元素查找
//存在返回该节点,失败返回NULL
Linklist SearchByData(Linklist L,datatype key)
{
//1,判空
if(L->len==0)
return NULL;
Linklist p=L;
for(int i=1;i<=L->len;i++)
{
p=p->next;
if(strcmp(key,p->data)==0)
{
return p;
}
}
return NULL;
}
//链表按元素修改
//e:查找的元素,如e存在修改key
int UpdataByData(Linklist L,datatype e,datatype key)
{
Linklist p=SearchByData(L,e);
if(p==NULL)
{
printf("%s不存在,修改失败\n",e);
return -1;
}
strcpy(p->data,key);
return 0;
}
//链表逆置
void LinklistRev(Linklist L)
{
Linklist p=L->next;//使用p节点保存第一个节点
L->next=NULL;//把头节点孤立
while(p)
{
Linklist t=p;//使用t保存p的第一个节点
p=p->next;//p向后移动
//把t头插在L头节点的后面
t->next=L->next;
L->next=t;
}
}
//链表排序
void LinklistSort(Linklist L)
{
Linklist p=L->next;
L->next=NULL;
while(p)
{
Linklist t=p;
p=p->next;
//头节点后面有其他节点
Linklist q=L;
while(q->next!=NULL && q->next->data>t->data)
{
q=q->next;
}
//头节点后面没有节点
t->next=q->next;
q->next=t;
}
}
//链表释放空间
void LinklistFree(Linklist L)
{
if(L==NULL)
return ;
for(int i=0;i<L->len;i++)
{
DeleteHead(L);
}
free(L);
L=NULL;
}
//main.c
#include "head.h"
int main(int argc, const char *argv[])
{
int flag;
Linklist L=LinklistCreateHead();
if(L==NULL)
return -1;
#if 0
//头插:永远在头结点后面插入
datatype e;
int n=5;
for(int i=0;i<n;i++)
{
scanf("%s",&e);
InsertHead(L,e);
}
#endif
//尾插:把新节点存到最后一个节点的后面
datatype e;
int n=5;
for(int i=0;i<n;i++)
{
scanf("%s",&e);
InsertRear(L,e);
}
printf("\n");
//遍历链表
LinklistShow(L);
#if 0
//头删
DeleteHead(L);
DeleteHead(L);
#endif
#if 0
//尾删
DeleteRear(L);
DeleteRear(L);
printf("\n");
//遍历链表
LinklistShow(L);
#endif
#if 0
//链表按位置插入
int pos;
printf("输入插入的位置:");
scanf("%d",&pos);
printf("输入插入的数据元素:");
scanf("%s",&e);
flag=InsertByPos(L,pos,e);
if(flag==0)
LinklistShow(L);
//链表按位置删除
printf("输入删除的位置:");
scanf("%d",&pos);
flag=DeleteByPos(L,pos);
if(flag==0)
LinklistShow(L);
//链表按位置查找
printf("输入查找的位置:");
scanf("%d",&pos);
SearchByPos(L,pos);
//链表按位置修改
printf("输入修改的位置:");
scanf("%d",&pos);
printf("输入修改的数据元素:");
scanf("%s",&e);
flag=UpdataByPos(L,pos,e);
if(flag==0)
LinklistShow(L);
//链表按元素查找
printf("输入查找的元素:");
scanf("%s",&e);
Linklist p=SearchByData(L,e);
if(p==NULL)
printf("查找失败\n");
else
printf("%s在链表中出现\n",p->data);
//链表修改:给定e,若e存在则修改为key
datatype key;
printf("\n输入要修改的元素:");
scanf(" %s",&e);
printf("输入修改后的值:");
scanf("%s",&key);
flag=UpdataByData(L,e,key);
if(flag==0)
LinklistShow(L);
#endif
#if 0
//链表按元素删除
printf("\n输入删除的元素:");
scanf("%s",&e);
flag=DeleteByData(L,e);
if(flag==0)
LinklistShow(L);
else
printf("\n按元素删除失败\n");
#endif
#if 0
//链表逆置:使用头节点后的节点一次实现头插
LinklistRev(L);
LinklistShow(L);
#endif
//链表排序:使用有序链表的思想
LinklistSort(L);
LinklistShow(L);
//空间释放
LinklistFree(L);
L=NULL;
return 0;
}
顺序表思维导图