版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、數(shù)據(jù)結(jié)構(gòu)課程設(shè)計報告課程名稱,題目名稱學(xué)生學(xué)院專業(yè)班級學(xué) 號學(xué)生姓名指導(dǎo)教師2010 年7 月8日一、 需求分析1 .圖書管理系統(tǒng)中圖書管理模塊包括圖書類型定義:書號、現(xiàn)存量、總存量,出版時 間為整型,定價為浮點(diǎn)型,書名、著者名為字符型,借閱指針、預(yù)約指針為讀者類型;讀者 類型定義:證號為整型、姓名為字符型,另外借閱類型和預(yù)約類型組合成其中的共用體類型。 B樹(2-3樹)類型定義:關(guān)鍵字個數(shù)和關(guān)鍵字?jǐn)?shù)組為整型、另外還有指向雙親的指針、指 向子樹的指針、記錄單元指針;B樹查找結(jié)果類型定義:節(jié)點(diǎn)指針、關(guān)鍵字序號和查找標(biāo)志變量為整型。2 .演示程序以用戶和計算機(jī)的對話方式進(jìn)行,在計算機(jī)終端上顯示“提
2、示信息”之后,由用戶在鍵盤上輸入演示程序中規(guī)定的運(yùn)算命令,相應(yīng)的輸入數(shù)據(jù)和運(yùn)算結(jié)果顯示在后面。 該演示系統(tǒng),沒有使用文件,全部數(shù)據(jù)放在內(nèi)存存放。四項基本業(yè)務(wù)都以書號為關(guān)鍵字進(jìn)行 的,采用了 B樹(2-3樹)對書號建立索引,以提高效率。3 .圖書管理系統(tǒng)實(shí)現(xiàn)功能:采編入庫:新書購入,將書號、書名、著者、冊數(shù)、出版時間添加入圖書賬目 中去,如果這種書在帳中已有,則只將總庫存量增加,每新增一個書號則以凹入 表的形式顯示B樹現(xiàn)狀。清除庫存:實(shí)現(xiàn)某本書的全部信息刪除操作,每清除一個書號則已以凹入表的形式顯示B樹現(xiàn)狀。圖書借閱:如果書的庫存量大于零時則執(zhí)行出借,登記借閱者的圖書證號和姓名,系統(tǒng)自動抓取當(dāng)前
3、借閱時間和計算歸還時間。圖書預(yù)約:如果某書庫存為零,則記錄預(yù)約者姓名和證號,系統(tǒng)自動抓取當(dāng)前 預(yù)約時間和取書時間。圖書歸還:注銷借閱者信息,并改變該書的現(xiàn)存量。作者專區(qū):輸入作者名字,系統(tǒng)將查找相應(yīng)作者全部著作并顯示出來。圖書信息:可以根據(jù)書號查閱此書基本信息、借閱信息和預(yù)約信息,亦可以查找全部圖書基本信息。二、概要設(shè)計1 .抽象數(shù)據(jù)類型B樹定義:ADT BTree數(shù)據(jù)對象:D是具有相同特性的數(shù)據(jù)元素的集合。各個數(shù)據(jù)元素均含有類型相同,可惟一標(biāo)識數(shù)據(jù)元素的關(guān)鍵字。數(shù)據(jù)關(guān)系:數(shù)據(jù)元素同屬于一個集合并且:一棵m階的B樹,或為空,或為滿足下列特性的m叉樹:樹中每個結(jié)點(diǎn)至多有 m棵子樹;若根結(jié)點(diǎn)不是葉
4、子結(jié)點(diǎn),則至少有兩棵子樹;除根之外的所有非終端結(jié)點(diǎn)至少有m/2 (取上限)棵子樹;所有的非終端結(jié)點(diǎn)包含下列信息數(shù)據(jù):(n,A0,K1,A1,K2,A2K3,,Kn,An)其中:Ki (i=1 , 2,n)為關(guān)鍵字,且 Ki<Ki+1 (i=1 , 2,n-1); Ai (i=0,n)為指向子樹根結(jié)點(diǎn)的指針, 且指針Ai-1所指子樹中所有結(jié)點(diǎn)的關(guān)鍵字均小于Ki(i=1 ,2,n), An所指子樹中所有結(jié)點(diǎn)的關(guān)鍵字均大于Kn , n (m/2(取上限)-1<=n<=m-1 )為關(guān)鍵字的個數(shù)基本操作:SearchBTree(T ,key);初始條件:B機(jī)T存在,key為和關(guān)鍵字類型
5、相同的給定值。操作結(jié)果:若T中存在關(guān)鍵字等于key的數(shù)據(jù)元素,則返回該元素的值或在表中的位置,否則返回“空”。Insert(T, i, k, P, recptr)初始條件:B機(jī)q和p存在,i、k是指定變量,recptr指針有效操作結(jié)果:將k和ap分別插入到q->keyi+1和q->ptri+1,并插入關(guān)鍵字為k的記錄recptr InsertBTree(&T ,e);初始條件:B機(jī)T存在,e為待插入的數(shù)據(jù)元素。操作結(jié)果:若T中步存在關(guān)鍵字等于 e.key的數(shù)據(jù)元素,則插入 e到T中。DeleteBTree(&T ,key);初始條件:B機(jī)T存在,key為和關(guān)鍵字類型
6、相同的給定值。操作結(jié)果:若T中存在其關(guān)鍵字等于 key的數(shù)據(jù)元素,則刪除之BTreeTraverse(BTree T,Visit)初始條件:B機(jī)T存在,Visit是對T結(jié)點(diǎn)的函數(shù)操作結(jié)果:遍歷 B機(jī)T,對每個結(jié)點(diǎn)調(diào)用 Visit函數(shù)ShowBTree( T );初始條件:B丁存在。操作結(jié)果:以凹入表形式顯示b機(jī)ADT BTree2 .系統(tǒng)時間類型定義:ADT Time數(shù)據(jù)對象:D=TM是各種整型類型的系統(tǒng)時間格式定義數(shù)據(jù)關(guān)系:數(shù)據(jù)元素同屬一個集合基本操作:GetDate(tm &tim)初始條件:系統(tǒng)時間運(yùn)行操作結(jié)果:獲取系統(tǒng)時間,賦予 tm變量timAddDate(tm &d
7、ate2,tm date1, int day)初始條件:系統(tǒng)時間date2、date1、day存在操作結(jié)果:把date1的日期加day天后賦給date2Earlier(tm date1,tm date2)初始條件:系統(tǒng)時間date2、date1存在操作結(jié)果:比較data1與date2日期的遲與早,如果date1早于或等于date2則返回TRUE, 否則返回FALSE。ADT Time3 .圖書管理類型定義:ADT BTree數(shù)據(jù)對象:D=ai | ai C BookType, i=1 , 2, 3, n, n>=0,其中每個數(shù)據(jù)元素ai含有類型相同,可惟一標(biāo)識數(shù)據(jù)元素的關(guān)鍵字?jǐn)?shù)據(jù)關(guān)系:數(shù)
8、據(jù)元素同屬一個集合基本操作:InitLibrary(&L );操作結(jié)果:初始化書庫L為空書庫。InsertBook(&L ,B ,result);初始條件:書庫 L和B已存在,result包含B書在書庫中的位置或應(yīng)該插入的位置。操作結(jié)果:如果書庫中已存在B書,則只將B書的庫存量增加,否則插入B書到書庫L中。DeleteBook(&L ,&B);初始條件:書庫L和B存在。操作結(jié)果:如果書庫中存在B書,則從書庫中刪除 B書的信息,并返回 OK,否則返回ERRORBorrowBook(L ,&B ,R);初始條件:書庫L存在,B書是書庫中的書并且可被讀者R借閱
9、。操作結(jié)果:彳t出一本 B書,記錄信息。ReturnBook(L ,&B ,R);初始條件:書庫L存在。操作結(jié)果:若書庫 L中有讀者R借閱B書的記錄,則注銷該記錄,改變 B書現(xiàn)存量, 并返回OK ,書不存在或無該讀者記錄則返回ERROR。BespeakBook(L ,&B ,R);初始條件:書庫L存在,B書是書庫中的書,R為借閱者。操作結(jié)果:為讀者 R預(yù)約B書。ListAuthor(L ,author);初始條件:書庫L存在,author為指定作者姓名操作結(jié)果:顯示author的所有著作。ShowBookinfo(L ,B );初始條件:書L存在。操作結(jié)果:若書庫L中存在書B,
10、則顯示B書基本信息并返回 OK,否則返回ERROR。 PrintAllBooks(L );初始條件:書庫L存在。操作結(jié)果:顯示所有圖書基本信息。ADT BTree3 .主程序int main()系統(tǒng)界面;初始化;for(;)顯示菜單信息;接受命令;處理命令;輸出結(jié)果;|4 .本程序有四個調(diào)用模塊主程序模塊圖書管理模塊B樹單元模塊系統(tǒng)時間模塊三、詳細(xì)設(shè)計抽象數(shù)據(jù)類型B樹算法詳解/*抽象數(shù)據(jù)類型B-樹存儲定義*/typedef BookNode Record;typedef struct BTNodeintkeynum;struct BTNode *parent;intkeym+1;struct
11、BTNode *ptrm+1;Record *recptrm+1;BTNode, *BTree;記錄指針為圖書結(jié)點(diǎn)類型結(jié)點(diǎn)關(guān)鍵字個數(shù)指向雙親指針關(guān)鍵字?jǐn)?shù)組,0號單元未用指向子樹指針記錄指針,0號單元未用/ B樹節(jié)點(diǎn)類型和 B樹類型typedef structBTNode *pt;inti;inttag;Result;指向找到的結(jié)點(diǎn)或應(yīng)該插入的結(jié)點(diǎn)1.m,在結(jié)點(diǎn)中關(guān)鍵字序號/ 1表示查找成功,0表示查找失敗 / B樹查找結(jié)果類型/*F*B-樹操作定義*/int Search(BTree p, int k)/* 在 B 機(jī)i p 中查找關(guān)鍵字 k 的位置 i,使得 p->nodei.key
12、w K< p->nodei+1.key*/ int i;for(i=0;i<p->keynum && p->keyi+1<=k;i+);return i;Result SearchBTree(BTree T, int k)在m階BT上查找關(guān)鍵字 K,返回結(jié)果(pt,i,tag)。若查找成功,則特征值 tag=1,指針pt所指結(jié)點(diǎn)中第i個關(guān)鍵字等于 K;否則特征值tag=0,等于K的/關(guān)鍵字應(yīng)插入在指針Pt所指結(jié)點(diǎn)中第i和第i+1個關(guān)鍵字之間。Result r; int i=1;BTree p=T,q=NULL;/初始化,p指向待查結(jié)點(diǎn),q指向
13、p的雙親int found=FALSE; while(p && !found) i=Search( p, k);/在 p->key1keynum中查找if(i && p->keyi=k) found=TRUE;找到待查關(guān)鍵字else q=p; p=p->ptri; if(found) r.pt=p; r.i=i; r.tag=1; else r.pt=q; r.i=i; r.tag=0; return r; void Insert(BTree &q, int i, int k, BTree ap, Record *recptr) /將k
14、和ap分別插入到q->keyi+1和q->ptri+1,并插入關(guān)鍵字為 k的記錄recprt for(int j=q->keynum;j>i;-j) /記錄、關(guān)鍵字、子樹指針后移q->keyj+1=q->keyj; q->ptrj+1=q->ptrj; q->recptrj+1=q->recptrj; q->keyi+1=k;插入記錄、關(guān)鍵字、子樹指針,關(guān)鍵字個數(shù)加q->ptri+1=ap; q->recptri+1=recptr; q->keynum+; if(ap) ap->parent = q;子樹
15、 ap 的父親指針void Split(BTree &q, int n, BTree &ap)/以n為分界將結(jié)點(diǎn)q分裂為兩個結(jié)點(diǎn),前一半保留,后一半移入新生結(jié)點(diǎn)apint i;ap = (BTree)malloc(sizeof(BTNode);ap->ptr0=q->ptrn;for(i = n+1;i <= m; i+)ap->keyi-n = q->keyi;ap->ptri-n = q->ptri; ap->recptri-n = q->recptri;ap->keynum = q->keynum - n;
16、q->keynum = n-1;ap->parent = q->parent;for (i=0; i<=m-n; i+)if(ap->ptri) ap->ptri->parent = ap;/申請新結(jié)點(diǎn)ap/ n后的關(guān)鍵字、子樹指針、記錄轉(zhuǎn)移到ap/計算ap的關(guān)鍵字個數(shù)/ q的關(guān)鍵字個數(shù)減少/ ap的子樹的父親指針void NewRoot(BTree &T, BTree p, int k, BTree ap,Record *recptr)/當(dāng)插入B樹日T為空或根結(jié)點(diǎn)分裂為p和ap兩個節(jié)點(diǎn),需建立一個根節(jié)點(diǎn)空間/本函數(shù)為T申請一塊空間,插入 p,
17、k,ap和記錄rec int InsertBTree(BTree &T, int k, BTree q, int i,Record *recptr)T = (BTree)malloc(sizeof(BTNode);T->keynum = 1;T->ptr0 = p;T->ptr1 = ap;T->key1 = k;T->recptr1 = recptr;if (p) p->parent= T;if (ap) ap->parent = T;T->parent = NULL;/插入/ T的子樹ap的父親指針/根節(jié)點(diǎn)雙親為NULL/在m階B機(jī)j
18、 T上結(jié)點(diǎn)*q的keyi與keyi+1之間插入關(guān)鍵字 K和記錄rec。/若引起結(jié)點(diǎn)過大,則沿雙親鏈進(jìn)行必要的結(jié)點(diǎn)分裂調(diào)整,使 T仍是m階B樹。BTree ap = NULL;int finished = FALSE;/ T是空樹,生成僅含關(guān)鍵字K的根結(jié)點(diǎn)*Tif (!q) NewRoot(T, NULL, k, NULL,recptr);elsewhile (finished) Insert(q, i, k, ap,recptr);/將 k 和 ap 插入到 q->keyi+1和 q->ptri+1if (q->keynum < m) finished = TRUE;/
19、 插入完成elseSplit(q, (m+1)/2, ap);k = q->key(m+1)/2;recptr = q->recptr(m+1)/2;if (q->parent) q = q->parent; i = Search(q, k); else finished = OVERFLOW;if (finished = OVERFLOW) NewRoot(T, q, k, ap,recptr);return OK;/分裂結(jié)點(diǎn)q/在雙親結(jié)點(diǎn)*q中查找k的插入位置/根節(jié)點(diǎn)已分裂為*q和*ap兩個結(jié)點(diǎn)/根結(jié)點(diǎn)已分裂為結(jié)點(diǎn)*q和*ap/需生成新根結(jié)點(diǎn)*T,q和ap為子樹指針
20、void TakePlace(BTree &q, int &i)/ *q結(jié)點(diǎn)的第i個關(guān)鍵字為k,用q的后繼關(guān)鍵字替代 q,且令q指向后繼所在結(jié)點(diǎn)BTree p = q;q = q->ptri;while(q->ptr0) q = q->ptr0;p->keyi = q->key1;p->recptri = q->recptr1;i = 1;void Del(BTree q, int i)/刪除q所指結(jié)點(diǎn)第i個關(guān)鍵字及其記錄for(;i < q->keynum ;i+)q->keyi = q->keyi+1;/查找
21、p的后繼/關(guān)鍵字代替/記錄代替代替后應(yīng)該刪除q所指結(jié)點(diǎn)的第1個關(guān)鍵字/關(guān)鍵字和記錄指針前移q->recptri = q->recptri+1;q->keynum -;/關(guān)鍵字?jǐn)?shù)目減 1int Borrow(BTree q)若q的兄弟結(jié)點(diǎn)關(guān)鍵字大于(m-1)/2,則從兄弟結(jié)點(diǎn)上移最?。ɑ蜃畲螅┑年P(guān)鍵字到雙親結(jié) 點(diǎn) 八、5/而將雙親結(jié)點(diǎn)中小于(或大于)且緊靠該關(guān)鍵字的關(guān)鍵字下移至q中,并返回OK,否則返回 EREOR。int i;BTree p = q->parent, b; for(i = 0 ; p->ptri != q;i+);/ p指向q的雙親結(jié)點(diǎn)/查找q在雙
22、親p的子樹位置if(i >= 0 && i+1 <= p->keynum && p->ptri+1->keynum > (m-1)/2)b = p->ptri+1;q->ptr1 = b->ptr0;q->key1 = p->keyi+1;q->recptr1 = p->recptri+1;p->keyi+1 = b->key1;p->recptri+1 = b->recptr1;for(i =1 ;i <= b->keynum;i+) b->
23、keyi = b->keyi+1;b->recptri = b->recptri+1;b->ptri-1 = b->ptri;若q的右兄弟關(guān)鍵字個數(shù)大于(m-1)/2/ b指向右兄弟結(jié)點(diǎn)/子樹指針也要同步移動/從父節(jié)點(diǎn)借第i+1個關(guān)鍵字/ b第一個關(guān)鍵字上移到父節(jié)點(diǎn)/ b第一個關(guān)鍵字上移,需把剩余記錄前移一位p->ptri-1->keynum > (m-1)/2)else if(i > 0 &&b = p->ptri-1;q->ptr1 = q->ptr0;q->ptr0 = b->ptrb-&
24、gt;keynum;q->key1 = p->keyi;q->recptr1 = p->recptri;p->keyi = b->keyb->keynum;p->recptri = b->recptrb->keynum;else return ERROR;q->keynum +;b->keynum -;for(i = 0 ;i <=q->keynum; i+)if(q->ptri) q->ptri->parent = q;return OK;若q的左兄弟關(guān)鍵字個數(shù)大約(m-1)/2/ b指向左
25、兄弟結(jié)點(diǎn)/從父節(jié)點(diǎn)借第i個關(guān)鍵字/將b最后一個關(guān)鍵字上移到父節(jié)點(diǎn)/無關(guān)鍵字大于(m-1)/2的兄弟/刷新q的子結(jié)點(diǎn)的雙親指針void Combine(BTree &q)/將q剩余部分和q的父結(jié)點(diǎn)的相關(guān)關(guān)鍵字合并到q兄弟中,然后釋放q,令q指向修改的兄弟int i, j ;/ p指向q的父親/插好q在父親p中的子樹位置BTree p = q->parent, b;for(i = 0; p->ptri != q; i+);if(i = 0)b = p->ptri+1;for(j = b->keynum ; j >= 0 卜)b->keyj+1 = b-&
26、gt;keyj;b->recptrj+1 = b->recptrj;b->ptrj+1 = b->ptrj;b->ptr0 = q->ptr0;b->key1 = p->key1;b->recptr1 = p->recptr1;else if(i > 0)b = p->ptri-1;b->keyb->keynum+1 = p->keyi;b->recptrb->keynum+1 = p->recptri;b->ptrb->keynum+1 = q->ptr0;if(i
27、= 0 | i = 1)/ 若for( ; i < p->keynum; i+)p->keyi = p->keyi+1;p->ptri = p->ptri+1;p->recptri = p->recptri+1;p->keynum -;b->keynum +;free(q);q = b;for(i = 0;i <= b->keynum; i+) if(b->ptri) b->ptri->parent = b;/如為0,則需合并為兄弟的第一個關(guān)鍵字/將b的關(guān)鍵字和記錄后移一位/合并若q在父親的子樹位置大約
28、0/需合并為兄弟b的最后一個關(guān)鍵字/合并i為0或1,需將父節(jié)點(diǎn)p關(guān)鍵字前移一位/ q指向修改的兄弟結(jié)點(diǎn)/刷新b的子結(jié)點(diǎn)的雙親指針 int DeleteBTree(BTree &T,int k)在m階B機(jī)T上刪除關(guān)鍵字 k及其對應(yīng)記錄,并返回 OK。/如T上不存在關(guān)鍵字 k,則返回ERROR。int x=k;BTreeq,b = NULL;intfinished = FALSE,i = 1;Result res = SearchBTree(T,k);/ 在 T 中查找關(guān)鍵字 kif(res.tag = 0 ) return ERROR;/ 未搜索到else q = res.pt;/ q指
29、向待刪結(jié)點(diǎn)i = res.i;if(q->ptr0) TakePlace(q, i);若q的子樹不空,(非底層結(jié)點(diǎn))/則以其后繼代之,且令 q指向后繼所在結(jié)點(diǎn)Del(q,i);/刪除q所指向結(jié)點(diǎn)中第i個關(guān)鍵字及記錄if(q->keynum>=(m-1)/2|!q->parent) 若刪除后關(guān)鍵字個數(shù)不小于(m-1)/2或q是根 finished = TRUE;/ 刪除完成if(q->keynum = 0 ) T = NULL;若q的關(guān)鍵字個數(shù)為0 ,則為空樹 while(!finished) if(Borrow(q) finished = TRUE; 若q的相鄰兄
30、弟結(jié)點(diǎn)關(guān)鍵字大于(m-1)/2,則從該兄弟結(jié)點(diǎn)上移一個最大(或最小)關(guān)鍵字到 /父節(jié)點(diǎn),從父節(jié)點(diǎn)借一關(guān)鍵字到qelse/若q相鄰兄弟關(guān)鍵字個數(shù)均等于廠m /2 7 -1Combine(q); /將q中的剩余部分和雙親中的相關(guān)關(guān)鍵字合并至q的一個兄弟中 q = q->parent;/ 檢查雙親if(q = T && T->keynum =0 )/若被刪結(jié)點(diǎn)的父節(jié)點(diǎn)是根T且T的關(guān)鍵字個數(shù)為0 T = T->ptr0;/ 新根T->parent = NULL; free(q);/刪除原雙親結(jié)點(diǎn)finished = TRUE;else if(q->keyn
31、um >= m/2) finished = TRUE;/合并后雙親關(guān)鍵字個數(shù)不少于(m-1)/2 ,完成 return OK ;void BTreeTraverse(BTree T,void ( *Visit)(BTree p)遍歷B機(jī)T ,對每個結(jié)點(diǎn)調(diào)用Visit函數(shù)if(!T) return;Visit(T);for(int i=0;i<=T->keynum;+i)if(T->ptri)BTreeTraverse(T->ptri,Visit);void ShowBTree(BTree T,short x = 8)遞歸以凹入表形式顯示B機(jī)每層的縮進(jìn)量為 x,初始
32、縮進(jìn)量為 8if(!T)return ;inti;printf("n");for(i = 0;i<=x;i+) putchar(' ');/ 縮進(jìn) xfor(i = 1 ;i <= T->keynum;i+) printf("%d,”,T->keyi);for(i = 0 ;i <= T->keynum;i+)/遞歸顯示子樹結(jié)點(diǎn)關(guān)鍵字ShowBTree(T->ptri,x+7);I*/*系統(tǒng)時間函數(shù)定義*/void GetDate(tm &tim)/獲取系統(tǒng)時間,賦予 tm結(jié)構(gòu)體變量tim time
33、_t curtime=time(0);tim = *localtime(&curtime);tim.tm_year += 1900;/ tm 年份少 1900 年tim.tm_mon +;/ tm month 從 0-11,故加 1void AddDate(tm &date2,tm date1, int day)/把date1的日期加 day天后賦給 date2date2.tm_year = date1.tm_year + (day/30 + date1.tm_mon) / 12;date2.tm_mon = (date1.tm_mon + (day / 30) % 12;da
34、te2.tm_mday = (date1.tm_mday + day) % 30;int Earlier(tm date1,tm date2)/比較data1與date2日期的遲與早,如果 date1早于或等于 date2則返回TRUE ,否則返 回 FALSE 。if(date1.tm_year < date2.tm_year) return TRUE;return TRUE;return ERROR;return TRUE;if(date1.tm_year > date2.tm_year) return ERROR;if(date1.tm_mon < date2.tm_m
35、on) if(date1.tm_mon > date2.tm_mon) if(date1.tm_mday <date2.tm_mday) return ERROR;/*圖書管理存儲定義*char*booksMAX_BOOKS;charauthorMAX_NAME_LEN;intbooks_counter;typedef struct ReaderNodeint cardnum;char rnameMAX_NAME_LEN;unionstructtmbordate;tmretdate;struct ReaderNode *nextr;structtmbespeakdate;struc
36、tReaderNode *nextb;ReaderNode,*ReaderType;/某作者作品數(shù)組/某作者姓名/某作者作品計數(shù)/借閱者/預(yù)約者結(jié)點(diǎn)/證號/姓名/借書日期/還書日期/下一個借閱者指針/預(yù)約日期/下一個預(yù)約者指針/讀者類型typedef struct BookNode/ 圖書結(jié)點(diǎn)intbooknum;/書號charbooknameMAX_BKNAME_LEN;/書名charwriterMAX_NAME_LEN;/作者名intcurrent;/現(xiàn)存量inttotal;/息庫存intpublishyear;/出版時間floatprice;/定價ReaderType reader;/借
37、閱者鏈表指針ReaderType bespeaker;/預(yù)約者鏈表指針 BookNode,*BookType;/ 圖書類型/*/*/圖書管理函數(shù)定義 */void InitLibrary(BTree &L )/初始化書庫L為空書庫。L = NULL;void InsertBook(BTree &L ,BookType B , Result res)/書庫L已存在,res包含B書在書庫L中的位置或應(yīng)該插入的位置如果書庫中已存在B書,則只將B書的庫存量增加,否則插入B書到書庫L中。if(res.tag=0) InsertBTree(L, B->booknum, res.pt,
38、 res.i, B); / 書庫中不存在該書,則插入 else BookType b=res.pt->recptrres.i; b->current=b->current+B->total;現(xiàn)存量增加b->total=b->total+B->total;總庫存增加 int DeleteBook(BTree &L ,BookType B) /如果書庫中存在 B書,則從書庫中刪除B書的信息,并返回 OK,否則返回ERROR if(DeleteBTree(L,B->booknum) return OK;刪除成功else return ERROR
39、;刪除失敗 int CanBorrow(BTree L,BookType B ,ReaderType R) /書庫L中存在B書。若B書現(xiàn)存量大于0,則可出借返回 TRUE /不能出借返回FALSE。if(B->current>0)return TRUE;現(xiàn)存量大于零else return FALSE;其他情況均不允許出借 void BorrowBook(BTree L ,BookType B ,ReaderType R) /書庫L存在,B書是書庫中的書并且可被讀者借閱 /借出一本B書,登記借閱者基本信息。 ReaderType r,pre; GetDate(R->bordat
40、e);/獲取系統(tǒng)當(dāng)前時間為借書時間日期AddDate(R->retdate,R->bordate,KEEP_DAYS);當(dāng)前時間加上 90 天為還書日期if(!B->reader)B->reader=R;暫無借閱者,直接登記else for(pre=r=B->reader;r;pre=r,r=r->nextr); pre->nextr=R;登記至借閱者表尾 B->current-; int ReturnBook(BTree L ,int booknum ,int cardnum,BookType &B ,ReaderType &R
41、) / booknum為還書書號,cardnum為還書者借閱證號, /若書庫中不存在書號為booknum的書,則搜索出錯,返回 -1/若有借閱記錄,則注銷該記錄,并用 B和R返回圖書信息和借閱者信息并返回1,/若沒有r、借閱的記錄,則用 B返回圖書信息,并返回 0Result res=SearchBTree(L,booknum);if(res.tag=0) return -1;B = res.pt->recptrres.i;/在B樹按書號搜索/用B記錄圖書信息ReaderType p=res.pt->recptrres.i->reader,pre=p; while(p)if(
42、pre=p&&p->cardnum = cardnum)/搜索借書者鏈表只有一個借書者R = p;B->current+;return 1;/現(xiàn)存量增1 if(p->cardnum=cardnum) R = p;pre ->nextr = p->nextr; B->current+;return 1;pre=p;p=p->nextr;return 0;多個借書者/現(xiàn)存量增1int BespeakBook(BookType B ,ReaderType R)/為讀者R預(yù)約借書,登記R的預(yù)約信息,成功返回OK ,否則返回ERROR 。if(B
43、->current>0) return ERROR;ReaderType r,pre;GetDate(R->bespeakdate);if(!B->bespeaker) B->bespeaker=R;elsefor(pre=r=B->bespeaker;r;pre=r,r=r->nextb) if(r->cardnum=R->cardnum) return ERROR; pre->nextb=R;return OK;void ListBookName(BTree p)/如果Bp結(jié)點(diǎn)中記錄里圖書著者名與全局變量author相同,/則將其
44、保存到指針數(shù)組books中int i;for(i=1;i<=p->keynum;+i)if(!strcmp(author,p->recptri->writer)booksbooks_counter=(char *)malloc(sizeof(char);strcpy(booksbooks_counter+,p->recptri->bookname);int ListAuthor(BTree L)/找出書庫中著者author的所有作品, 如果找到該author的著作,則返回保存到 books指針數(shù)組中。TRUE ,否貝U返回 ERRORintBTreeTrav
45、erse(L,ListBookName); if(books_counter>0) /遍歷書庫,調(diào)用 ListBookName存儲某著者作品printf("nn");printf(" *%-7s for(i = 0; i<books_counter ;i+) printf("t%-23sn",booksi);作品清單 *n",author);return TRUE;else return ERROR;表格頭部格式void PrintH() printf("n");printf(" *print
46、f(" 書號書名圖書基本信息 *著者 I現(xiàn)存I總庫存I出版年份I定價I 'n");I 'n");顯示B書基本信息void PrintD(BookType B) printf(" I111111I n");printf(" %-4d%-20s%-11s%-4d%-4d%-6d%61f",B->booknum,B->bookname,B->writer,B->current,B->total,B->publishyear,B->price);表格底部格式void Prin
47、tT()n");printf("n | void PrintAll(BTree p)/顯示B樹每個節(jié)點(diǎn)的記錄信息int i;for(i=1;i<=p->keynum;+i)PrintD(p->recptri);void PrintBook(BookType B)/以表格形式顯示一本書的基本信息PrintH();PrintD(B);PrintT();printf("n");void PrintAllbooks( BTree L)顯示書庫L所有圖書信息PrintH();BTreeTraverse(L, PrintAll);PrintT();
48、void SortBorrower(BookType B)對B書的借書者鏈表進(jìn)行按日期排序,日期早的排在前面int count;ReaderType p, pre, head;if(B->reader)for(count = 0 ,p = B->reader; p; p = p->nextr) count+;/ 統(tǒng)計借書人數(shù)head = (ReaderType)malloc(sizeof(ReaderNode);head->nextr = B->reader;while(count- > 1)/ 冒泡法排序pre = head;p = pre->nex
49、tr->nextr;while(p)if(!Earlier(pre->nextr->bordate,p->bordate) / 把日期早的排前面,否則交換pre->nextr->nextr = p->nextr;p->nextr = pre->nextr;pre->nextr = p;pre = p;p = p->nextr->nextr; elsep = p->nextr;pre = pre->nextr; B->reader = head->nextr;free(head);void SortB
50、espeaker(BookType B)對B書的預(yù)約者鏈表進(jìn)行按日期排序,日期早的排在前面int count;ReaderType p, pre, head;if(B->bespeaker)for(count= 0 ,p=B->bespeaker; p; p=p->nextb) count+;/ 統(tǒng)計預(yù)約人數(shù)head = (ReaderType)malloc(sizeof(ReaderNode);head->nextb = B->bespeaker;while(count- > 1)/ 冒泡排序pre = head;p = pre->nextb->
51、;nextb;while(p)if(!Earlier(pre->nextb->bespeakdate,p->bespeakdate)/ / 把日期早的排在前 面,否則交換pre->nextb->nextb = p->nextb;p->nextb = pre->nextb;pre->nextb = p;pre = p;p = p->nextb->nextb; elsep = p->nextb; pre = pre->nextb; B->bespeaker = head->nextb; free(head);
52、void PrintBorrower(BookType B)/借閱者名單信息ReaderType p;char rpos27="超期","正常"tmtoday;GetDate(today);printf(" * printf("n");printf(" 借閱證號I 姓名圖書借閱信息 *出借日期 I歸還日期I狀態(tài)printf(" In");n");n");for(p = B->reader; p; p = p->nextr)printf(" %-5d %-
53、6s%-4d 年2d 月 2d 日 %-4d 年2d 月 2d 日 %-6sn",p->cardnum,p->rname,p->bordate.tm_year,p->bordate.tm_mon,p->bordate.tm_mday,p->retdate.tm_year,p->retdate.tm_mon,p->retdate.tm_mday,rposEarlier(today,p->retdate); void PrintBespeaker(BookType B)/預(yù)約者名單信息ReaderType p;char bpos27="超期","正常"tmtoday,temp;GetDate(today);printf(" *圖書預(yù)約信息 *n");printf("n");printf("預(yù)約證號printf(" I1姓名I預(yù)約日期超期日期狀態(tài)n&quo
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 茶園互換合同
- 財務(wù)合同管理崗位風(fēng)險
- 貝雷片租賃合同范本
- 保險合同十句話
- 山西省2024八年級物理上冊第六章質(zhì)量與密度專題訓(xùn)練12.理解質(zhì)量和密度課件新版新人教版
- 深圳市中薈高級中學(xué)2024-2025學(xué)年高三上學(xué)期期中考試數(shù)學(xué)試卷
- 《船用鋼質(zhì)斜梯》
- 貴州省貴陽市觀觀山湖區(qū)美的中學(xué)2024-2025學(xué)年九年級上學(xué)期11月期中考試化學(xué)試題
- 無鹵低煙阻燃電纜料相關(guān)項目投資計劃書
- 石英玻璃管(棒)相關(guān)行業(yè)投資規(guī)劃報告
- 臨床決策分析課件
- 外科學(xué)(1)智慧樹知到答案章節(jié)測試2023年溫州醫(yī)科大學(xué)
- DBJ15302023年廣東省鋁合金門窗工程設(shè)計、施工及驗收規(guī)范
- 兒童口腔醫(yī)學(xué)課件 乳牙活髓切斷術(shù)及預(yù)成冠修復(fù)術(shù)
- 風(fēng)險加權(quán)資產(chǎn)
- 涉及人血液、尿液標(biāo)本采集知情同意書模板
- GB/T 9797-2022金屬及其他無機(jī)覆蓋層鎳、鎳+鉻、銅+鎳和銅+鎳+鉻電鍍層
- JJF 1183-2007溫度變送器校準(zhǔn)規(guī)范
- 針刺傷專項測試卷含答案
- GB/T 30026-2021起重用鋼制短環(huán)鏈?zhǔn)謩渔準(zhǔn)胶J用高精度鏈TH級
- 工程付款(含預(yù)付款)申請表
評論
0/150
提交評論