基于链式存储结构图书信息表各项操作

​

#include<iostream>
#include<iomanip>
#include<string>
using namespace std;
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define MAXSIZE 1000            
typedef struct
{
	string no;  //编号
	string name;//书名
	float price;//价格
}Book;
typedef struct LNode
{
	int length;         //数据域(只计算头结点L的length值)
	Book data;    	//数据域
	struct LNode *next; //指针域
}LNode, *LinkList;
int InitList_L(LinkList &L)       //注意引用&符号:形参变化,改变实参
{
	L = new LNode;
	L->next = NULL;
	return OK;
}
int Input_L(LinkList &L)          //注意引用&符号:形参变化,改变实参
{
	LinkList p = L;                 //用p存储链表L的头指针,即p指向链表的首元结点
	string no0;
	string name0;
	float price0;
	while (cin >> no0 >> name0 >> price0)
	{
		if (no0 == "0"&&name0 == "0"&&price0 == 0.0)//非法输入
			break;
		else
		{
			LinkList q = new LNode; //定义一个新指针q
			q->data.no = no0;       //编号   
			q->data.name = name0;   //书名
			q->data.price = price0; //价格
			q->next = NULL;         //尾指针为0
			p->next = q;            //将q插在p的后面
			p = q;                  //更新p,p指向q
		}
	}
	return OK;
}
int Input_L2(LinkList &L)             //注意引用&符号:形参变化,改变实参
{
	LinkList p = L;                    //尾插法:p是链表的尾指针
	int n;
	cin >> n;
	while (n--)             	     //循环输入n本书的数据
	{
		LinkList q = new LNode;        //定义新指针q并分配地址    
		cin >> q->data.no >> q->data.name >> q->data.price;//数据
		q->next = NULL;                                 //指针
		p->next = q;                   //将新指针q插在尾指针p的后面
		p = q;                         //更新指针p,指向尾结点
	}
	return OK;
}

int Input_L1(LinkList &L)            //注意引用&符号:形参变化,改变实参
{
	int n;
	cin >> n;
	while (n--)            	    //头插法存储n本书的数据
	{
		LinkList p = new LNode;       //定义新指针
		cin >> p->data.no >> p->data.name >> p->data.price;//输入数据
		p->next = L->next;            //将首元结点插在新节点后面
		L->next = p;                  //将新节点插在头结点后面
	}
	return OK;
}


int  Length_L(LinkList &L)        //注意引用&符号:形参变化,改变实参
{
	LinkList p = L;                 //用p存储链表L的头指针,即p指向链表的头结点
	L->length = 0;                  //链表的表长L->length初始化为0       
	while (p->next)                //注意链表的头指针L不可改变,所以用p来操作
	{
		L->length++;              //下一个结点存在,则链表的表长+1
		p = p->next;                //p更新   
	}
	//cout << L->length << endl;        //输出表长
	return OK;
}

int Output_L(LinkList L)
{
	LinkList p = L;		//用p存储链表L的头指针,即p指向链表的头结点
	while (p->next)
	{
		cout << p->next->data.no << " " << p->next->data.name << " " << fixed << setprecision(2) << p->next->data.price << endl;
		p = p->next;
	}
	return OK;
}
int Sort_L(LinkList &L)        	  //注意引用&符号:形参变化,改变实参
{
	for (int i = 0; i < L->length - 1; i++)
	{
		LinkList p = L->next;       //每轮冒泡排序从首元结点开始
		for (int j = 0; j < L->length - 1 - i; j++)
		{
			if (p->data.price < p->next->data.price)//降序排序
			{
				Book t = p->data;
				p->data = p->next->data;
				p->next->data = t;
			}
			p = p->next;
		}
	}
	return OK;
}

int Avg_Revise_L(LinkList &L)  	//修改价格
{
	LinkList p = L->next;   	//p指向链表的首元结点
	float sum = 0;   		//总价,累加之前一定记住sum赋值为0
	float avg_price;    	//均价
	while (p)      		//若结点存在
	{
		sum += p->data.price; 	//累加
		p = p->next;     		//更新p指针,指向下一个结点
	}
	avg_price = sum / L->length;  	//求均值并输出
	cout << fixed << setprecision(2) << avg_price << endl;
	p = L->next;     		//p指向链表的首元结点
	while (p)      		//若结点存在
	{
		if (p->data.price < avg_price) //与均价比较
			p->data.price = p->data.price*1.2;
		else
			p->data.price = p->data.price*1.1;
		p = p->next;     		//更新p指针,指向下一个结点
	}
	return OK;
}
int Max_L(LinkList L)                //求最大值
{
	LinkList p = L->next;              //p指向首元结点
	int max = p->data.price;           //首元结点的数据设为max
	int count = 0;		     //最高价书,则数目
	while (p->next)                   //若下一个结点存在,则与max比较
	{
		if (max < p->next->data.price)
			max = p->next->data.price; //更新max值
		p = p->next;                   //更新指针p,指向下一个结点
	}
	p = L->next;                       //p指向首元结点
	while (p)                         //若结点存在,则与max比较
	{
		if (p->data.price == max)       //若为最高价书,则count加1
			count++;
		p = p->next;                   //更新指针p,指向下一个结点
	}
	cout << count << endl;               //输出最高价书的总数
	p = L->next;                       //p指向首元结点
	while (p)                         //若结点存在,则与max比较    
	{
		if (p->data.price == max)       //若为最高价书,则输出相关信息
			cout << p->data.no << " " << p->data.name << " " << fixed << setprecision(2) << p->data.price << endl;
		p = p->next;                   //更新指针p,指向下一个结点
	}
	return OK;
}
int Favorite_book_L(LinkList &L1)    	//注意引用&符号:形参变化,改变实参
{
	int n;
	cin >> n;                            	//查询n本最爱图书
	LinkList L2 = new LNode;            	//创建链表L2,存储待查找的最爱图书
	LinkList p, q = L2;                	//q指向链表L2的头结点
	for (int i = 0; i < n; i++)            	//尾插法:存储n本最爱图书的书名
	{
		LinkList s = new LNode;        	//定义新结点s并分配地址
		cin >> s->data.name;            	//输入书名
		s->next = NULL;                	//处理新结点s的地址域
		q->next = s;                    	//将新结点s插在尾结点q的后面
		q = s;                        	//更新尾指针q,指向尾结点
	}
	q = L2->next;                         //q指向链表L2的首元结点
	while (q)                        	//当结点q存在时,依次与L链表中的书名比较
	{
		int count = 0;                	//最爱图书可能多本重名
		int flag = 0;                     //假定该书不存在
		p = L1->next;                     //p指向链表L1的首元结点
		while (p)                   	//当结点p存在时,进行比较
		{
			if (q->data.name == p->data.name)//书名相同
			{
				flag = 1;                	//该书存在
				count++;            	//数目+1
			}
			p = p->next;                	//与L中的下一本书进行比较
		}
		if (flag == 0)                    	//与L中的书比较一轮后,不存在
			cout << "Sorry,there is no your favourite!" << endl;
		else                        	//与L中的书比较一轮后,存在
		{
			cout << count << endl;        	//输出该书的总数
			p = L1->next;                	//p指向链表L的首元结点
			while (p)                	//当结点p存在,进行比较
			{
				if (q->data.name == p->data.name)//书名相同,输出相关信息
					cout << p->data.no << " " << p->data.name << " " << fixed << setprecision(2) << p->data.price << endl;
				p = p->next;            	//与L中的下一本书进行比较
			}
		}
		q = q->next;                    	//继续查询下一本最爱的图书
	}
	return OK;
}
int Locate_L(LinkList L)            	//链表逻辑相邻,物理不一定相邻
{
	int n;
	cin >> n;
	int i, a[100];
	for (i = 1; i <= n; i++)                	//输入n本书的编号            
		cin >> a[i];
	i = 1;                            	//从第1个位置开始定位                
	while (i <= n)                        	//依次定位n本图书
	{
		LinkList p = L;                	//p指向头结点
		if (1 <= a[i] && a[i] <= L->length)	//第i个位置合理
		{
			a[i]--;//从1开始计数 
			while (a[i]--)            	//循环a[i]次,循环结束,定位成功,输出相关信息            
				p = p->next;
			cout << p->next->data.no << " " << p->next->data.name << " " << fixed << setprecision(2) << p->next->data.price << endl;
		}
		else
			cout << "Sorry,the book on the best position doesn't exist!" << endl;
		i++;                        	//继续定位下一本图书
	}
	return OK;
}
int Insert_L(LinkList &L)            	//注意引用&符号:形参变化,改变实参
{
	int n;                            	//插在第n个位置
	LinkList p, b = new LNode;            	//用结点b存储新书的信息
	cin >> n >> b->data.no >> b->data.name >> b->data.price;//存储该书的信息
	if (1 <= n && n <= 1 + L->length)            //插入位置合理,有1+L->length个位置可插入
	{
		p = L;                        	//p指向链表的头结点,指向位置0
		n--;				//为了下面循环n-1次
		while (n--)                    	//定位到位置n-1
			p = p->next;                	//循环结束时,p->next指向位置n
		b->next = p->next;               	//将结点p->next插在结点b后面
		p->next = b;                    	//将结点b插在结点p后面
		p = L->next;                    	//p指向链表的首元结点
		while (p)                    	//若结点p存在,则输出相关信息
		{
			cout << p->data.no << " " << p->data.name << " " << fixed << setprecision(2) << p->data.price << endl;
			p = p->next;                	//更新结点p,指向下一个结点
		}
	}
	else                            	//插入位置非法
		cout << "Sorry,the position to be inserted is invalid!" << endl;
	return OK;
}
int Delete_L(LinkList &L)               //注意引用&符号:形参变化,改变实参
{
	LinkList p = L;                       //p指向链表的头结点,指向位置0
	int n;                              //删除第n个位置的结点
	cin >> n;
	if (1 <= n && n <= L->length)              //删除位置合理,有L->length个位置可删除
	{
		n--;                            //为了下面循环n-1次
		while (n--)                      //定位到位置n-1
			p = p->next;                  //循环结束时,p->next指向位置n
		LinkList s = p->next;             //保留待删除结点
		p->next = p->next->next;          //将结点p->next->next插在结点p后面
		delete s;                       //删除结点s,释放内存
		p = L->next;                      //p指向首元结点
		while (p)                        //若结点p存在,则输出相关信息
		{
			cout << p->data.no << " " << p->data.name << " " << fixed << setprecision(2) << p->data.price << endl;
			p = p->next;                  //更新结点p,指向下一个结点
		}
	}
	else                                //删除位置非法
		cout << "Sorry,the position to be deleted is invalid!" << endl;
	return OK;
}
int Delete_same_L(LinkList &L)        	//注意引用&符号:形参变化,改变实参
{
	LinkList p = L->next;                	//p指向首元结点
	while (p)                        	//从首元结点开始查重删除
	{
		LinkList q = p;                	//q指向p结点
		while (q->next)                	//当q结点存在时,与p比较
		{
			if (q->next->data.no == p->data.no)//查重判断
			{
				LinkList s = q->next;    	//保存待删除结点
				q->next = q->next->next;
				delete s;            	//删除结点,释放内存
			}
			else
				q = q->next;            	//更新指针q,指向下一个结点 
		}
		p = p->next;    			//更新指针p,指向下一个结点 
	}
	return OK;
}
int Output_L2(LinkList L)
{
	Length_L(L);
	cout << L->length << endl;
	LinkList p = L;
	while (p->next)                	//用p存储链表L的头指针,即p指向链表的头结点
	{
		cout << p->next->data.no << " " << p->next->data.name << " " << fixed << setprecision(2) << p->next->data.price << endl;
		p = p->next;
	}
	return OK;
}

int main()
{
	LinkList L;        		//定义LinkList类型的指针L
	InitList_L(L);    		//创建:给指针L分配地址,初始化
	//Input_L(L);        		//输入数据
	//Input_L1(L);           //前插法
	Input_L2(L);			//尾插法
	//Length_L(L);    		//输出链表L的表长L->length    
	//Sort_L(L);                	//降序排序
	//Avg_Revise_L(L);            //修改价格
	//Output_L(L);    		//输出链表L
	//Max_L(L);          //求价格最高图书
	//Favorite_book_L(L);
	//Locate_L(L);                    	//定位图书,并输出相关信息
	//Insert_L(L);			//插入
	//Delete_L(L);				//删除
	Delete_same_L(L);			//去重
	Output_L2(L);			//输出
	return 0;
}

[点击并拖拽以移动]
​

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值