2023/2/5 顺序表与单链表
顺序表练习:请实现购物车系统,把商品[商品名称,商品属性、价格,个数]信息存储到顺序表中,请完成一下操作操作
1,在堆区申请空间
2,实现顺序表数据元素在表尾录入
3,实现顺序表输出
4,实现顺序表按下标插入商品信息
5,实现顺序表按下标删除商品信息
6,查找商品名称key是否在购物车信息中出现
7,修改商品名称key的购买数量, 修改为n
8,删除最贵的商品信息
9,对商品总价实现升序排序
10,如果有两个商品名称相同的商品信息,则去重
11,释放堆区空间
head.h
#ifndef __HEAD_H__
#define __HEAD_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSIZE 20
typedef struct
{
char name[20];//名称
char arriture[20];//属性
float price;//价格
int num;//个数
}Goods;
typedef struct
{
Goods data[MAXSIZE];
int len;
}Seqlist;
//堆区申请空间
Seqlist *CreateSpace();
//判空
int SeqlistEmpty(Seqlist *s);
//判满
int SeqlistFull(Seqlist *s);
//顺序表数据元素在表尾录入
void InsertByRear(Seqlist *s,Goods e);
//顺序表输出
void SeqlistOutput(Seqlist *s);
//顺序表按下标插入商品信息
void InsertBySub(Seqlist *s,int sub,Goods e);
//顺序表按下标删除商品信息
void DeleteBySub(Seqlist *s,int sub);
//查找商品名称key是否在购物车中出现
int SearchByName(Seqlist *s,char *key);
//修改商品名称key的购买数量,修改为n
void UpdateNumByName(Seqlist *s,char *key,int n);
//删除最贵的商品信息
void DeleteMaxPrice(Seqlist *s);
//求商品总价
float SumPrice(Goods e);
//对商品总价实现升序排序
void SortSumPrice(Seqlist *s);
//如果有两个商品名称相同的商品信息,则去重
void RemoveSameName(Seqlist *s);
#endif
main.c
#include "head.h"
int main(int argc, const char *argv[])
{
int num,sub;
Seqlist *s=CreateSpace();
Goods e;
char key[20]="";
int n;
if(s==NULL)
{
return 0;
}
while(1)
{
printf("=================购物车==============\n");
printf("1.录入商品\t2.输出已录入商品信息\n3.插入商品信息\t4.删除所选商品信息\n");
printf("5.查找商品\t6.修改商品的购买数量\n7.删除最贵商品的信息\t8.对商品总价升序排序\n");
printf("9.商品名称去重\t0.退出购物车\n");
printf("===================END===============\n");
printf("请输入选择的操作对应的数字:");
scanf("%d",&num);
switch(num)
{
case 1:{
printf("输入商品名称:");
scanf("%s",e.name);
printf("输入商品属性:");
scanf("%s",e.arriture);
printf("输入商品价格:");
scanf("%f",&e.price);
printf("输入商品个数:");
scanf("%d",&e.num);
InsertByRear(s,e);
break;
};
case 2:{
SeqlistOutput(s);
break;
};
case 3:{
printf("输入插入的下标:");
scanf("%d",&sub);
printf("输入插入的商品名称:");
scanf("%s",e.name);
printf("输入插入的商品属性:");
scanf("%s",e.arriture);
printf("输入插入的商品价格:");
scanf("%f",&e.price);
printf("输入插入的商品个数:");
scanf("%d",&e.num);
InsertBySub(s,sub,e);
break;
};
case 4:{
printf("输入删除商品的下标:");
scanf("%d",&sub);
DeleteBySub(s,sub);
break;
};
case 5:{
printf("输入查找的商品名称:");
scanf("%s",key);
int judge=SearchByName(s,key);
if(judge==-1)
{
printf("%s不在购物车中\n",key);
}else{
printf("%s在购物车中\n",key);
}
break;
};
case 6:{
printf("输入修改的商品名称:");
scanf("%s",key);
printf("输入修改后的数量:");
scanf("%d",&n);
UpdateNumByName(s,key,n);
break;
};
case 7:{
DeleteMaxPrice(s);
break;
};
case 8:{
SortSumPrice(s);
break;
};
case 9:{
RemoveSameName(s);
break;
};
case 0:{
free(s);
s=NULL;
return 0;
};
default:{
printf("出错了!\n");
break;
};
}
}
return 0;
}
test.c
#include "head.h"
//堆区申请空间
Seqlist *CreateSpace()
{
Seqlist *s=(Seqlist*)malloc(sizeof(Seqlist));
if(s==NULL)
{
return NULL;
}
s->len=0;
return s;
}
//顺序表判空,空返回-1,否则返回0
int SeqlistEmpty(Seqlist *s)
{
if(s->len==0)
{
return -1;
}
return 0;
}
//顺序表判满,满返回-1,否则返回0
int SeqlistFull(Seqlist *s)
{
if(s->len==MAXSIZE)
{
return -1;
}
return 0;
}
//顺序表数据元素在表尾录入
void InsertByRear(Seqlist *s,Goods e)
{
if(SeqlistFull(s))
{
printf("输入不合法!\n");
return;
}
s->data[s->len++]=e;
}
//顺序表输出
void SeqlistOutput(Seqlist *s)
{
for(int i=0;i<s->len;i++)
{
printf("名称:%s 属性:%s 价格:%.2f 数量:%d\n",s->data[i].name,s->data[i].arriture,s->data[i].price,s->data[i].num);
}
printf("\n");
}
//按下标插入商品信息
void InsertBySub(Seqlist *s,int sub,Goods e)
{
if(SeqlistFull(s)||sub<0||sub>s->len)
{
printf("输入不合法!\n");
return;
}
for(int i=s->len-1;i>=sub;i--)
{
s->data[i+1]=s->data[i];
}
s->data[sub]=e;
s->len++;
}
//按下标删除商品信息
void DeleteBySub(Seqlist *s,int sub)
{
if(SeqlistEmpty(s)||sub<0||sub>=s->len)
{
printf("输入不合法!\n");
return;
}
for(int i=sub;i<s->len-1;i++)
{
s->data[i]=s->data[i+1];
}
s->len--;
}
//查找商品名称key是否出现在购物车中
//出现返回下标,否则返回-1
int SearchByName(Seqlist *s,char *key)
{
if(SeqlistEmpty(s))
{
return -1;
}
for(int i=0;i<s->len;i++)
{
if(strcmp(key,s->data[i].name)==0)
{
return i;
}
}
}
//修改商品名称为key的购买数量,修改为n
void UpdateNumByName(Seqlist *s,char *key,int n)
{
if(SeqlistEmpty(s))
{
printf("输入不合法!\n");
return;
}
for(int i=0;i<s->len;i++)
{
if(strcmp(key,s->data[i].name)==0)
{
printf("找到了\n");
s->data[i].num=n;
}
}
}
//删除最贵的商品信息
void DeleteMaxPrice(Seqlist *s)
{
if(SeqlistEmpty(s))
{
printf("输入不合法!\n");
return;
}
int flag;
for(int i=0;i<s->len-1;i++)
{
if(s->data[i].price>s->data[i+1].price)
{
flag=i;
}
}
DeleteBySub(s,flag);
}
//求商品总价
float SumPrice(Goods e)
{
return e.price * e.num;
}
//对商品总价实现升序排序
void SortSumPrice(Seqlist *s)
{
int i,j;
Goods temp;
for(i=0;i<s->len-1;i++)
{
int count=0;
for(j=0;j<s->len-1-i;j++)
{
if(SumPrice(s->data[j])>SumPrice(s->data[j+1]))
{
temp=s->data[j];
s->data[j]=s->data[j+1];
s->data[j+1]=temp;
count++;
}
}
if(count==0)
{
break;
}
}
}
//如果有两个商品名称相同的商品信息,则去重
void RemoveSameName(Seqlist *s)
{
int i,j;
for(i=0;i<s->len;i++)
{
for(j=i+1;j<s->len;j++)
{
if(strcmp(s->data[i].name,s->data[j].name)==0)
{
DeleteBySub(s,j);
j--;
}
}
}
}
单向链表练习: 链表中存储数据类型为字符串,请完成以下功能
1.在堆区申请空间
2.实现头插、头删、尾插、尾删
3,遍历链表
4,在任意位置插入
5,任意位置删除
6,按元素修改
7,按元素查找
8,单向链表逆置
9,链表降序排序
10,释放链表空间
head.h
#ifndef __HEAD_H__
#define __HEAD_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSIZE 20
typedef struct node
{
union{
int len;
char data[MAXSIZE];
};
struct node *next;
}*Linklist,Node;
//创建头结点
Linklist LinklistCreateHead();
//创建普通结点
Linklist LinklistCreateNode();
//头插
void InsertHead(Linklist L,char *e);
//头删
void DeleteHead(Linklist L);
//尾插
void InsertRear(Linklist L,char *e);
//尾删
void DeleteRear(Linklist L);
//遍历链表
void LinklistShow(Linklist L);
//按位置插入
int InsertByPos(Linklist L,int pos,char *e);
//按位置删除
int DeleteByPos(Linklist L,int pos);
//按元素查找
Linklist SearchByData(Linklist L,char *key);
//按元素修改
int UpdateByData(Linklist L,char *e,char *key);
//单向链表逆置
void LinklistRev(Linklist L);
//链表降序排序
void LinklistSort(Linklist L);
//释放空间
void LinklistFree(Linklist L);
#endif
main.c
#include "head.h"
int main(int argc, const char *argv[])
{
Linklist L=LinklistCreateHead();
if(L==NULL)
{
return -1;
}
char e[MAXSIZE]="";
char key[MAXSIZE]="";
int n;
printf("输入插入数据个数:");
scanf("%d",&n);
/*
//头插:在头结点后插入
for(int i=0;i<n;i++)
{
scanf("%s",e);
InsertHead(L,e);
}
*/
//尾插:在最后一个结点插入新结点
for(int i=0;i<n;i++)
{
scanf("%s",e);
InsertRear(L,e);
}
//遍历链表
LinklistShow(L);
//头删:删除头结点后的结点
DeleteHead(L);
printf("删除头结点后的一个结点后链表为:\n");
LinklistShow(L);
//尾删:删除最后一个结点
DeleteRear(L);
printf("删除最后一个结点后链表为:\n");
LinklistShow(L);
//链表按位置插入
int pos,flag;
printf("输入插入的位置:");
scanf("%d",&pos);
printf("输入插入的数据元素:");
scanf("%s",e);
flag=InsertByPos(L,pos,e);
if(flag==0)
{
LinklistShow(L);
}else if(flag==-1)
{
printf("出错了!\n");
}
//链表按位置删除
printf("输入删除的位置:");
scanf("%d",&pos);
flag=DeleteByPos(L,pos);
if(flag==0)
{
LinklistShow(L);
}else if(flag==-1)
{
printf("出错了!\n");
}
//链表按元素查找
printf("输入查找的元素:");
scanf("%s",e);
Linklist p=SearchByData(L,e);
if(p==NULL)
{
printf("查找失败!\n");
}else{
printf("查找的结点元素为:%s\n",p->data);
}
//链表按元素修改
printf("输入查找元素:");
scanf("%s",e);
printf("输入修改的元素:");
scanf("%s",key);
flag=UpdateByData(L,e,key);
if(flag==0)
{
LinklistShow(L);
}else if(flag==-1)
{
printf("出错了!\n");
}
//链表逆置,使用头结点后的结点依次头插
LinklistRev(L);
printf("逆置后的链表为:\n");
LinklistShow(L);
//链表排序
LinklistSort(L);
printf("排序后的链表为:\n");
LinklistShow(L);
//释放空间
LinklistFree(L);
L=NULL;
return 0;
}
test.c
#include "head.h"
//创建头结点
Linklist LinklistCreateHead()
{
Linklist L=(Linklist)malloc(sizeof(Node));
if(L==NULL)
{
return NULL;
}
L->len=0;
L->next=NULL;
return L;
}
//创建普通结点
Linklist LinklistCreateNode()
{
Linklist p=(Linklist)malloc(sizeof(Node));
if(p==NULL)
{
return NULL;
}
p->data;
p->next=NULL;
return p;
}
//头插
void InsertHead(Linklist L,char *e)
{
Linklist p=LinklistCreateNode();
if(p==NULL)
{
return;
}
strcpy(p->data,e);
p->next=L->next;
L->next=p;
L->len++;
}
//头删
void DeleteHead(Linklist L)
{
if(L->len==0)
{
return;
}
Linklist p=L->next;
L->next=p->next;
free(p);
p=NULL;
L->len--;
}
//尾插
void InsertRear(Linklist L,char *e)
{
Linklist p=LinklistCreateNode();
Linklist q=L;
if(p==NULL)
{
return;
}
while(q->next)
{
q=q->next;
}
strcpy(p->data,e);
q->next=p;
L->len++;
}
//尾删
void DeleteRear(Linklist L)
{
if(L->len==0)
{
return;
}
Linklist p=L;
while(p->next->next)
{
p=p->next;
}
free(p->next);
p->next=NULL;
L->len--;
}
//遍历链表
void LinklistShow(Linklist L)
{
while(L->next)
{
L=L->next;
printf("%s\t",L->data);
}
printf("\n");
}
//按位置插入
int InsertByPos(Linklist L,int pos,char *e)
{
Linklist q=LinklistCreateNode();
if(L->len==0||pos<1||pos>L->len+1||q==NULL)
{
return -1;
}
Linklist p=L;
for(int i=0;i<pos-1;i++)
{
p=p->next;
}
strcpy(q->data,e);
q->next=p->next;
p->next=q;
L->len++;
return 0;
}
//按位置删除
int DeleteByPos(Linklist L,int pos)
{
if(L->len==0||pos<1||pos>L->len+1)
{
return -1;
}
Linklist p=L;
for(int i=0;i<pos-1;i++)
{
p=p->next;
}
Linklist q=p->next;
p->next=q->next;
free(q);
q=NULL;
L->len--;
return 0;
}
//按元素查找
Linklist SearchByData(Linklist L,char *e)
{
if(L->len==0)
{
return NULL;
}
Linklist p=L;
for(int i=0;i<L->len;i++)
{
p=p->next;
if(strcmp(p->data,e)==0)
{
return p;
}
}
return NULL;
}
//按元素修改
int UpdateByData(Linklist L,char *e,char *key)
{
Linklist p=SearchByData(L,e);
if(p==NULL)
{
return -1;
}
strcpy(p->data,key);
return 0;
}
//单向链表逆置
void LinklistRev(Linklist L)
{
Linklist p=L->next;
L->next=NULL;
Linklist temp;
while(p)
{
temp=p;
p=p->next;
temp->next=L->next;
L->next=temp;
}
}
//链表降序排序
void LinklistSort(Linklist L)
{
Linklist p=L->next;
L->next=NULL;
while(p)
{
Linklist temp=p;
p=p->next;
Linklist q=L;
while(q->next&&strcmp(q->next->data,temp->data)>0)
{
q=q->next;
}
temp->next=q->next;
q->next=temp;
}
}
//释放空间
void LinklistFree(Linklist L)
{
if(L->len==0)
{
return;
}
for(int i=0;i<L->len;i++)
{
DeleteRear(L);
}
}