2023-2-4假期作业--顺序表-链表

1.顺序表练习:

请实现购物车系统,把商品【商品名称,商品属性、价格,个数】信息存储到顺序表中,请完成一下操作操作

结构体定义

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;
}

2023-2-4假期作业--顺序表-链表_第1张图片

2.单向链表练习:

链表中存储数据类型为字符串,请完成以下功能
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;
}

顺序表思维导图

2023-2-4假期作业--顺序表-链表_第2张图片

你可能感兴趣的:(数据结构,链表,数据结构)