文章目錄
#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;
}
}
}