#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;
}
[点击并拖拽以移动]
基于链式存储结构图书信息表各项操作
于 2021-10-15 12:30:17 首次发布