#include<iostream>
#include<string>
#include<iomanip>
#include<fstream>
using namespace std;
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status; //Status 是函式回傳值型別,其值是函式結果狀態代碼。
typedef int ElemType; //ElemType 為可定義的資料型別,此設為int型別
struct Book {
string id;//ISBN
string name;//書名
double price;//定價
};
typedef struct LNode {
Book data; //結點的資料域
struct LNode *next; //結點的指標域
} LNode, *LinkList; //LinkList為指向結構體LNode的指標型別
string head_1, head_2, head_3;
int length;
Status InitList_L(LinkList &L) { //演算法2.6 單鏈表的初始化
//構造一個空的單鏈表L
L = new LNode; //生成新結點作為頭結點,用頭指標L指向頭結點
L->next = NULL; //頭結點的指標域置空
return OK;
}
Status GetElem_L(LinkList L, int i, Book &e) { //演算法2.7 單鏈表的取值
//在帶頭結點的單鏈表L中查找第i個元素
//用e回傳L中第i個資料元素的值
int j;
LinkList p;
p = L->next;
j = 1; //初始化,p指向第一個結點,j為計數器
while (j < i && p) { //順鏈域向后掃描,直到p指向第i個元素或p為空
p = p->next; //p指向下一個結點
++j; //計數器j相應加1
}
if (!p || j > i)
return ERROR; //i值不合法i>n或i<=0
e = p->data; //取第i個結點的資料域
return OK;
} //GetElem_L
LNode *LocateElem_L(LinkList L, int e) { //演算法2.8 按值查找
//在帶頭結點的單鏈表L中查找值為e的元素
LinkList p;
p = L->next;
while (p && p->data.price != e)//順鏈域向后掃描,直到p為慷訓p所指結點的資料域等于e
p = p->next; //p指向下一個結點
return p; //查找成功回傳值為e的結點地址p,查找失敗p為NULL
} //LocateElem_L
Status ListInsert_L(LinkList &L, int i, Book &e) { //演算法2.9 單鏈表的插入
//在帶頭結點的單鏈表L中第i個位置插入值為e的新結點
int j;
LinkList p, s;
p = L;
j = 0;
while (p && j < i - 1) {
p = p->next;
++j;
}//查找第i?1個結點,p指向該結點
if (!p || j > i - 1)
return ERROR; //i>n+1或者i<1
s = new LNode; //生成新結點*s
s->data = e; //將結點*s的資料域置為e
s->next = p->next; //將結點*s的指標域指向結點ai
p->next = s; //將結點*p的指標域指向結點*s
++length;
return OK;
} //ListInsert_L
Status ListDelete_L(LinkList &L, int i) { //演算法2.9 單鏈表的洗掉
//在帶頭結點的單鏈表L中,洗掉第i個位置
LinkList p, q;
int j;
p = L;
j = 0;
while ((p->next) && (j < i - 1)) //查找第i?1個結點,p指向該結點
{
p = p->next;
++j;
}
if (!(p->next) || (j > i - 1))
return ERROR; //當i>n或i<1時,洗掉位置不合理
q = p->next; //臨時保存被刪結點的地址以備釋放
p->next = q->next; //改變洗掉結點前驅結點的指標域
delete q; //釋放洗掉結點的空間
--length;
return OK;
} //ListDelete_L
void CreateList_H(LinkList &L, int n) { //演算法2.11 前插法創建單鏈表
//逆位序輸入n個元素的值,建立到頭結點的單鏈表L
LinkList p;
L = new LNode;
L->next = NULL; //先建立一個帶頭結點的空鏈表
length = 0;
fstream file;
file.open("book.txt");
if (!file) {
cout << "未找到相關檔案,無法打開!" << endl;
exit(ERROR);
}
file >> head_1 >> head_2 >> head_3;
while (!file.eof()) {
p = new LNode; //生成新結點*p
file >> p->data.id >> p->data.name >> p->data.price; //輸入元素值賦給新結點*p的資料域
p->next = L->next;
L->next = p; //將新結點*p插入到頭結點之后
length++;//同時對鏈表長度進行統計
}
file.close();
} //CreateList_F
void CreateList_R(LinkList &L, int n) { //演算法2.12 后插法創建單鏈表
//正位序輸入n個元素的值,建立帶表頭結點的單鏈表L
LinkList p, r;
L = new LNode;
L->next = NULL; //先建立一個帶頭結點的空鏈表
r = L; //尾指標r指向頭結點
length = 0;
fstream file; //打開檔案進行讀寫操作
file.open("book.txt");
if (!file) {
cout << "未找到相關檔案,無法打開!" << endl;
exit(ERROR);
}
file >> head_1 >> head_2 >> head_3;
while (!file.eof()) { //將檔案中的資訊運用后插法插入到鏈表中
p = new LNode;//生成新結點
file >> p->data.id >> p->data.name >> p->data.price;//輸入元素值賦給新結點*p的資料域
p->next = NULL;
r->next = p;//將新結點*p插入尾結點*r之后
r = p;//r指向新的尾結點*p
length++; //同時對鏈表長度進行統計
}
file.close();
} //CreateList_L
int main() {
int a, n, choose;
double price;
Book e;
LinkList L, p;
cout << "1. 建立\n";
cout << "2. 輸入\n";
cout << "3. 取值\n";
cout << "4. 查找\n";
cout << "5. 插入\n";
cout << "6. 洗掉\n";
cout << "7. 輸出\n";
cout << "0. 退出\n\n";
choose = -1;
while (choose != 0) {
cout << "請選擇:";
cin >> choose;
switch (choose) {
case 1: //建立一個單鏈表
if (InitList_L(L))
cout << "成功建立鏈表!\n\n";
break;
case 2: //使用后插法創建單鏈表
CreateList_R(L, length);
cout << "輸入 book.txt 資訊完畢\n\n";
break;
case 3: //單鏈表的按序號取值
cout << "請輸入一個位置用來取值:";
cin >> a;
if (GetElem_L(L, a, e)) {
cout << "查找成功\n";
cout << "第" << a << "本圖書的資訊是:\n";
cout << left << setw(15) << e.id << "\t" << left << setw(50)
<< e.name << "\t" << left << setw(5) << e.price << endl
<< endl;
} else
cout << "查找失敗\n\n";
break;
case 4: //單鏈表的按值查找
cout << "請輸入所要查找價格:";
cin >> price;
if (LocateElem_L(L, price) != NULL) {
cout << "查找成功\n";
cout << "該價格對應的書名為:" << LocateElem_L(L, price)->data.name
<< endl << endl;
} else
cout << "查找失敗! 定價" << price << " 沒有找到\n\n";
break;
case 5: //單鏈表的插入
cout << "請輸入插入的位置和書的資訊,包括:編號 書名 價格(用空格隔開):";
cin >> a;
cin >> e.id >> e.name >> e.price;
if (ListInsert_L(L, a, e))
cout << "插入成功.\n\n";
else
cout << "插入失敗!\n\n";
break;
case 6: //單鏈表的洗掉
cout << "請輸入所要洗掉的書籍的位置:";
cin >> a;
if (ListDelete_L(L, a))
cout << "洗掉成功!\n\n";
else
cout << "洗掉失敗!\n\n";
break;
case 7: //單鏈表的輸出
cout << "當前圖書系統資訊(鏈表)讀出:\n";
p = L->next;
while (p) {
cout << left << setw(15) << p->data.id << "\t" << left << setw(
50) << p->data.name << "\t" << left << setw(5)
<< p->data.price << endl;
p = p->next;
uj5u.com熱心網友回復:
代碼不全,問題不明確~轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/232210.html
標籤:C語言
