文章目录
#include<stdio.h>
#include<iostream>
#include<stdlib.h>
#include<algorithm>
#include<string>
using namespace std;
typedef struct BOOK{
string ISBN;
string name;
int rate;
}BOOK;
typedef struct BOOK* ElemType;
typedef struct BookSystem* LinkBook;
typedef struct BookSystem{
ElemType data;
LinkBook next;
}BookSystem;
//初始化
void InitBook(LinkBook &B){
B = new BookSystem;
B->data = new BOOK;
B->next = NULL;
return;
}
//查找(名字)
LinkBook LocateBook(LinkBook B, string name){
while (B){
if (B->data->name == name)return B;
B = B->next;
}
return NULL;
}
//插入(递归)
void InsertBook(LinkBook &B, BOOK e){
if (!B){
InitBook(B);
*B->data = e;
}
else{
InsertBook(B->next, e);
}
return;
}
//删除(名字)(递归)
void DeleteBook(LinkBook &B, string name,LinkBook f){
//f是B父亲用来挂接
if (!B)return;//未找到边界
if (B->data->name == name){
LinkBook q = B;
B = B->next;
if (f)
f->next = B;
delete q;
return;
}
else{
f = B;
DeleteBook(B->next, name,f);
}
return;
}
//修改(名字)
void ChangeBook(LinkBook &B, string OLD,string NEW){
LinkBook change = (LocateBook(B, OLD));
if (change)
change->data->name = NEW;
else
cout << "没有该书目"<<endl;
return;
}
//找链尾
LinkBook LocateRear(LinkBook B){
while (B->next)
B = B->next;
return B;
}
void swap(BOOK &a, BOOK &b){
BOOK t = a;
a = b;
b = t;
return;
}
//找枢轴
LinkBook GetPrivot(LinkBook start,LinkBook end){
LinkBook p=start, q=p->next;
BOOK t, key = *start->data;
while (q!=end){
while (q->data->ISBN.compare(key.ISBN) ==1&& q != end)
q = q->next;
if (q->data->ISBN.compare(key.ISBN)==-1){
p = p->next;
swap(*p->data,* q->data);
}
}
swap(*start->data, *p->data);
return p;
}
//排序
void QuickSortBook(LinkBook start,LinkBook end){
if (start != end){
LinkBook privot = GetPrivot(start, end);
if (privot)
QuickSortBook(start, privot);
if (privot->next)
QuickSortBook(privot->next, end);
}
}
//计数
int LengthBook(LinkBook B){
int len = 0;
for (; B; len++)
B = B->next;
return len;
}
//输出
void OutPut(LinkBook B){
if (!B){ cout << "空" << endl; return; }
while (B){
cout << B->data->ISBN << " " << B->data->name << " " << B->data->rate << endl;
B = B->next;
}
return;
}
//菜单
void menu(LinkBook B){
printf("1.Locate;2.Insert;3.Delete;4.Change;5.QuickSort;6.Length;7.OutPut;8.end\n");
char op;
ElemType temp=new BOOK,result=new BOOK;
while (1){
fflush(stdin);
op = getchar();
fflush(stdin);
switch (op)
{
case '1':
printf("查找(名字):");
cin >> temp->name;
if (LocateBook(B, temp->name)){
*result = *LocateBook(B, temp->name)->data;
cout << result->ISBN << " " << result->name << " " << result->rate << endl;
}
else
cout << "未找到\n";
break;
case '2':
printf("插入(IBSN/name/rate):");
cin >> temp->ISBN >> temp->name >> temp->rate;
InsertBook(B, *temp);
break;
case '3':
printf("删除(name):");
cin >> temp->name;
DeleteBook(B, temp->name,NULL);
break;
case '4':
printf("修改(名字 OLD/NEW):");
cin >> temp->name>>result->name;
ChangeBook(B, temp->name, result->name);
break;
case '5':
printf("排序:\n");
QuickSortBook(B, LocateRear(B));
OutPut(B);
break;
case '6':
printf("表长:%d\n", LengthBook(B));
break;
case '7':
OutPut(B);
break;
case '8':
return;
default:
cout << "WRONG\n";
break;
}
}
}
int main(){
LinkBook book=NULL;
menu(book);
system("PAUSE");
return 0;
}
0.结构体
typedef struct BOOK{
string ISBN;
string name;
int rate;
}BOOK;
typedef struct BOOK* ElemType;
typedef struct BookSystem* LinkBook;
typedef struct BookSystem{
ElemType data;
LinkBook next;
}BookSystem;
1.初始化
//初始化
void InitBook(LinkBook &B){
B = new BookSystem;
B->data = new BOOK;
B->next = NULL;
return;
}
2.查找(按名字)
//查找(名字)
LinkBook LocateBook(LinkBook B, string name){
while (B){
if (B->data->name == name)return B;
B = B->next;
}
return NULL;
}
3.插入(递归)
注意
1.可以利用初始化函数
利用该节点空时就初始化然后填数来递归实现插入
2.用递归和引用传递的好处是
用next递归:InsertBook(B->next, e);
递归完函数后B也发生了变化且B的根不变
//插入(递归)
void InsertBook(LinkBook &B, BOOK e){
if (!B){
InitBook(B);
*B->data = e;
}
else{
InsertBook(B->next, e);
}
return;
}
4.删除(名字)(递归)(删除的是链表中先出现符合条件的的那个名字)
注意
1.被删除节点的父亲->next需要重新挂接到被删除节点的后导;若为根节点则无父亲,不需挂接
2.在改接了之后,要把被删除的节点的存储空间释放
3.找完未找到时需要一个边界if (!B)return;
4.用递归和引用传递的好处是
用next递归:DeleteBook(B->next, name,f);
递归完函数后B也发生了变化且B的根不变(若是根被删根就是变成next)
5.不能利用查找,因为直接查找并不知道其父亲是谁,无法挂接
void DeleteBook(LinkBook &B, string name,LinkBook f){
//f是B父亲用来挂接
if (!B)return;//未找到边界
if (B->data->name == name){
LinkBook q = B;
B = B->next;
if (f)
f->next = B;
delete q;
return;
}
else{
f = B;
DeleteBook(B->next, name,f);
}
return;
}
5.修改(名字)(修改的是链表中先出现符合条件的的那个名字)
注意
可以利用查找函数:若NULL则是没有该数目,否则就直接修改
//修改(名字)
void ChangeBook(LinkBook &B, string OLD,string NEW){
LinkBook change = (LocateBook(B, OLD));
if (change)
change->data->name = NEW;
else
cout << "没有该书目"<<endl;
return;
}
6.排序(快排)
学习于
https://blog.csdn.net/otuhacker/article/details/10366563
6.1注意
1.string字符串的比较若><=不能用时就用A.compare(B):大于就是1;等于就是0;小于就是-1
6.2原理
6.3链表可以做单边的快排
1即q=start,p=q->next;其中p,q之间的数大于关键字,p之前的数小于关键字,最后把start的值和p交换让p作为枢轴
2按照枢轴分成左右表递归执行快排直到左右表空结束
6.4其中子函数的作用
1.找链尾:为了一开始的start和end
2.找枢轴:就是一次快排,再通过枢轴分成左右表递归执行快排
3.swap:交换两个的值
//找链尾
LinkBook LocateRear(LinkBook B){
while (B->next)
B = B->next;
return B;
}
void swap(BOOK &a, BOOK &b){
BOOK t = a;
a = b;
b = t;
return;
}
//找枢轴
LinkBook GetPrivot(LinkBook start,LinkBook end){
LinkBook p=start, q=p->next;
BOOK t, key = *start->data;
while (q!=end){
while (q->data->ISBN.compare(key.ISBN) ==1&& q != end)
q = q->next;
if (q->data->ISBN.compare(key.ISBN)==-1){
p = p->next;
swap(*p->data,* q->data);
}
}
swap(*start->data, *p->data);
return p;
}
//排序
void QuickSortBook(LinkBook start,LinkBook end){
if (start != end){
LinkBook privot = GetPrivot(start, end);
if (privot)
QuickSortBook(start, privot);
if (privot->next)
QuickSortBook(privot->next, end);
}
}
7.计数
//计数
int LengthBook(LinkBook B){
int len = 0;
for (; B; len++)
B = B->next;
return len;
}
8.输出
//输出
void OutPut(LinkBook B){
if (!B){ cout << "空" << endl; return; }
while (B){
cout << B->data->ISBN << " " << B->data->name << " " << B->data->rate << endl;
B = B->next;
}
return;
}
9.菜单
注意
1.fflush(stdin);是清空键盘缓存区stdin的
fflush(stdin);
op = getchar();
fflush(stdin);
这样之前多余的键盘缓存区的内容不会被getchar()吸收,之后的多余输出也不会影响操作中输入的数据,确保了op吸收了输出的一串字符中的第一个,其他的都被清空了(包括\n)
2.赋值注意一定要加星号键,以免把地址赋出去,因为temp,result是所有操作暂存数的地方,但是地址都不变
//菜单
void menu(LinkBook B){
printf("1.Locate;2.Insert;3.Delete;4.Change;5.QuickSort;6.Length;7.OutPut;8.end\n");
char op;
ElemType temp=new BOOK,result=new BOOK;
while (1){
fflush(stdin);
op = getchar();
fflush(stdin);
switch (op)
{
case '1':
printf("查找(名字):");
cin >> temp->name;
if (LocateBook(B, temp->name)){
*result = *LocateBook(B, temp->name)->data;
cout << result->ISBN << " " << result->name << " " << result->rate << endl;
}
else
cout << "未找到\n";
break;
case '2':
printf("插入(IBSN/name/rate):");
cin >> temp->ISBN >> temp->name >> temp->rate;
InsertBook(B, *temp);
break;
case '3':
printf("删除(name):");
cin >> temp->name;
DeleteBook(B, temp->name,NULL);
break;
case '4':
printf("修改(名字 OLD/NEW):");
cin >> temp->name>>result->name;
ChangeBook(B, temp->name, result->name);
break;
case '5':
printf("排序:\n");
QuickSortBook(B, LocateRear(B));
OutPut(B);
break;
case '6':
printf("表长:%d\n", LengthBook(B));
break;
case '7':
OutPut(B);
break;
case '8':
return;
default:
cout << "WRONG\n";
break;
}
}
}