

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、<p><b> 需求分析</b></p><p> 1. 圖書管理系統(tǒng)中圖書管理模塊包括圖書類型定義:書號、現(xiàn)存量、總存量,出版時間為整型,定價為浮點型,書名、著者名為字符型,借閱指針、預約指針為讀者類型;讀者類型定義:證號為整型、姓名為字符型,另外借閱類型和預約類型組合成其中的共用體類型。</p><p> B樹(2-3樹)類型定義:關(guān)鍵字個數(shù)和關(guān)
2、鍵字數(shù)組為整型、另外還有指向雙親的指針、指向子樹的指針、記錄單元指針;B樹查找結(jié)果類型定義: 節(jié)點指針、關(guān)鍵字序號和查找標志變量為整型。</p><p> 2. 演示程序以用戶和計算機的對話方式進行,在計算機終端上顯示“提示信息”之后,由用戶在鍵盤上輸入演示程序中規(guī)定的運算命令,相應的輸入數(shù)據(jù)和運算結(jié)果顯示在后面。該演示系統(tǒng),沒有使用文件,全部數(shù)據(jù)放在內(nèi)存存放。四項基本業(yè)務都以書號為關(guān)鍵字進行的,采用了B樹(2
3、-3樹)對書號建立索引,以提高效率。</p><p> 圖書管理系統(tǒng)實現(xiàn)功能:</p><p> ①采編入庫:新書購入,將書號、書名、著者、冊數(shù)、出版時間添加入圖書賬目中去,如果這種書在帳中已有,則只將總庫存量增加,每新增一個書號則以凹入表的形式顯示B樹現(xiàn)狀。</p><p> ?、谇宄龓齑妫?實現(xiàn)某本書的全部信息刪除操作 ,每清除一個書號則已以凹入表的形式顯示
4、B樹現(xiàn)狀。③圖書借閱: 如果書的庫存量大于零時則執(zhí)行出借,登記借閱者的圖書證號和姓名,系統(tǒng)自動抓取當前借閱時間和計算歸還時間。④圖書預約:如果某書庫存為零,則記錄預約者姓名和證號,系統(tǒng)自動抓取當前預約時間和取書時間。</p><p> ?、輬D書歸還:注銷借閱者信息,并改變該書的現(xiàn)存量。⑥作者專區(qū):輸入作者名字,系統(tǒng)將查找相應作者全部著作并顯示出來。</p><p> ⑦圖書信息:可
5、以根據(jù)書號查閱此書基本信息、借閱信息和預約信息,亦可以查找全部圖書基本信息。</p><p><b> 概要設(shè)計</b></p><p> 1.抽象數(shù)據(jù)類型B樹定義:</p><p> ADTBTree{</p><p> 數(shù)據(jù)對象:D是具有相同特性的數(shù)據(jù)元素的集合。各個數(shù)據(jù)元素均含有類型相同,可惟一標識數(shù)據(jù)元
6、素的關(guān)鍵字。</p><p> 數(shù)據(jù)關(guān)系:數(shù)據(jù)元素同屬于一個集合并且:</p><p> 一棵m階的B樹,或為空,或為滿足下列特性的m叉樹:</p><p> 樹中每個結(jié)點至多有m棵子樹;</p><p> 若根結(jié)點不是葉子結(jié)點,則至少有兩棵子樹;</p><p> 除根之外的所有非終端結(jié)點至少有m/2(取上
7、限)棵子樹;</p><p> 所有的非終端結(jié)點包含下列信息數(shù)據(jù):</p><p> (n,A0,K1,A1,K2,A2,K3,……,Kn,An)</p><p> 其中:Ki(i=1,2,……n)為關(guān)鍵字,且Ki<Ki+1(i=1,2,……n-1);Ai(i=0,……n)為指向子樹根結(jié)點的指針,且指針Ai-1所指子樹中所有結(jié)點的關(guān)鍵字均小于Ki(i=1
8、,2,……n),An所指子樹中所有結(jié)點的關(guān)鍵字均大于Kn,n(m/2(取上限)-1<=n<=m-1)為關(guān)鍵字的個數(shù)</p><p><b> 基本操作:</b></p><p> SearchBTree(T ,key);</p><p> 初始條件:B樹T存在,key為和關(guān)鍵字類型相同的給定值。</p><
9、p> 操作結(jié)果:若T中存在關(guān)鍵字等于key的數(shù)據(jù)元素,則返回該元素的值或在表中的位置,否則返回“空”。</p><p> Insert(T, i, k, P, recptr)</p><p> 初始條件:B樹q和p存在,i、k是指定變量,recptr指針有效</p><p> 操作結(jié)果:將k和ap分別插入到q->key[i+1]和q->pt
10、r[i+1],并插入關(guān)鍵字為k的記錄recptr </p><p> InsertBTree(&T ,e);</p><p> 初始條件:B樹T存在,e為待插入的數(shù)據(jù)元素。</p><p> 操作結(jié)果:若T中步存在關(guān)鍵字等于e.key的數(shù)據(jù)元素,則插入e到T中。</p><p> DeleteBTree(&T ,key
11、);</p><p> 初始條件:B樹T存在,key為和關(guān)鍵字類型相同的給定值。</p><p> 操作結(jié)果:若T中存在其關(guān)鍵字等于key的數(shù)據(jù)元素,則刪除之</p><p> BTreeTraverse(BTree T,Visit)</p><p> 初始條件:B樹T存在,Visit是對T結(jié)點的函數(shù)</p><p
12、> 操作結(jié)果:遍歷B樹T,對每個結(jié)點調(diào)用Visit函數(shù)</p><p> ShowBTree( T );</p><p> 初始條件:B樹T存在。</p><p> 操作結(jié)果:以凹入表形式顯示B樹T。</p><p> }ADTBTree</p><p> 2 .系統(tǒng)時間類型定義:</p>
13、;<p><b> ADTTime{</b></p><p> 數(shù)據(jù)對象:D={TM 是各種整型類型的系統(tǒng)時間格式定義}</p><p> 數(shù)據(jù)關(guān)系:數(shù)據(jù)元素同屬一個集合</p><p><b> 基本操作:</b></p><p> GetDate(tm &tim
14、)</p><p> 初始條件:系統(tǒng)時間運行</p><p> 操作結(jié)果:獲取系統(tǒng)時間,賦予tm變量tim</p><p> AddDate(tm &date2,tm date1, intday)</p><p> 初始條件:系統(tǒng)時間date2、date1、day存在</p><p> 操作結(jié)果:把
15、date1的日期加day天后賦給date2</p><p> Earlier(tm date1,tm date2)</p><p> 初始條件:系統(tǒng)時間date2、date1存在</p><p> 操作結(jié)果:比較data1與date2日期的遲與早,如果date1早于或等于date2則返回TRUE,否則返回FALSE。</p><p>
16、 }ADT Time</p><p> 3. 圖書管理類型定義:</p><p> ADTBTree{</p><p> 數(shù)據(jù)對象:D={ai | ai∈BookType,i=1,2,3,……n,n>=0,其中</p><p> 每個數(shù)據(jù)元素ai含有類型相同,可惟一標識數(shù)據(jù)元素的關(guān)鍵字}</p><p&g
17、t; 數(shù)據(jù)關(guān)系:數(shù)據(jù)元素同屬一個集合</p><p><b> 基本操作:</b></p><p> InitLibrary(&L );</p><p> 操作結(jié)果:初始化書庫L為空書庫。</p><p> InsertBook(&L ,B ,result);</p><p&
18、gt; 初始條件:書庫L和B已存在,result包含B書在書庫中的位置或應該插入的位置。</p><p> 操作結(jié)果:如果書庫中已存在B書,則只將B書的庫存量增加,否則插入B書到書庫L中。</p><p> DeleteBook(&L ,&B);</p><p> 初始條件:書庫L和B存在。</p><p> 操作結(jié)
19、果:如果書庫中存在B書,則從書庫中刪除B書的信息,并返回OK,否則返回ERROR</p><p> BorrowBook(L ,&B ,R);</p><p> 初始條件:書庫L存在,B書是書庫中的書并且可被讀者R借閱。</p><p> 操作結(jié)果:借出一本B書,記錄信息。</p><p> ReturnBook(L ,&am
20、p;B ,R);</p><p> 初始條件:書庫L存在。</p><p> 操作結(jié)果:若書庫L中有讀者R借閱B書的記錄,則注銷該記錄,改變B書現(xiàn)存量,并返回OK,書不存在或無該讀者記錄則返回ERROR。</p><p> BespeakBook(L ,&B ,R);</p><p> 初始條件:書庫L存在,B書是書庫中的書,
21、R為借閱者。</p><p> 操作結(jié)果:為讀者R預約B書。</p><p> ListAuthor(L ,author);</p><p> 初始條件:書庫L存在,author為指定作者姓名</p><p> 操作結(jié)果:顯示author的所有著作。</p><p> ShowBookinfo(L ,B );
22、</p><p> 初始條件:書L存在。</p><p> 操作結(jié)果:若書庫L中存在書B,則顯示B書基本信息并返回OK,否則返回ERROR。</p><p> PrintAllBooks(L );</p><p> 初始條件:書庫L存在。</p><p> 操作結(jié)果:顯示所有圖書基本信息。</p>
23、<p> }ADT BTree</p><p><b> 3. 主程序</b></p><p> int main()</p><p><b> {</b></p><p><b> 系統(tǒng)界面; </b></p><p>&l
24、t;b> 初始化;</b></p><p> for( ; ; )</p><p><b> {</b></p><p><b> 顯示菜單信息;</b></p><p><b> 接受命令;</b></p><p><
25、b> 處理命令;</b></p><p><b> 輸出結(jié)果;</b></p><p><b> }</b></p><p><b> }|</b></p><p> 本程序有四個調(diào)用模塊</p><p><b>
26、 主程序模塊</b></p><p><b> ↓</b></p><p><b> 圖書管理模塊</b></p><p><b> ↓ ↓</b></p><p> B樹單元模塊 系統(tǒng)時間模塊</p><p><b&
27、gt; 詳細設(shè)計</b></p><p> 《抽象數(shù)據(jù)類型B樹算法詳解》</p><p> /**************************抽象數(shù)據(jù)類型 B- 樹存儲定義*************************/</p><p> typedef BookNode Record;
28、 //記錄指針為圖書結(jié)點類型</p><p> typedef struct BTNode{</p><p> int keynum; //結(jié)點關(guān)鍵字個數(shù)</p><p> struct BTNode *parent; //指
29、向雙親指針</p><p> int key[m+1]; //關(guān)鍵字數(shù)組,0號單元未用</p><p> struct BTNode *ptr[m+1]; //指向子樹指針</p><p> Record *recptr[m+1];
30、 //記錄指針,0號單元未用</p><p> }BTNode, *BTree; // B樹節(jié)點類型和B樹類型</p><p> typedef struct{</p><p> BTNode *pt;
31、 //指向找到的結(jié)點或應該插入的結(jié)點</p><p> int i; //1...m,在結(jié)點中關(guān)鍵字序號</p><p> int tag; // 1表示查找成功,0表示查找失敗</p><p>
32、 }Result; // B樹查找結(jié)果類型</p><p> /****************************************************************************/</p><p> /**************************B- 樹操作定義*
33、***********************************/</p><p> int Search(BTree p, int k)</p><p> /* 在B樹p中查找關(guān)鍵字k的位置i,使得p->node[i].key≤K<p->node[i+1].key*/</p><p><b> {</b></p&
34、gt;<p><b> int i;</b></p><p> for(i=0;i<p->keynum && p->key[i+1]<=k;i++);</p><p><b> return i;</b></p><p><b> }</b>
35、;</p><p> ResultSearchBTree(BTree T, int k)</p><p> // 在m階B樹T上查找關(guān)鍵字K,返回結(jié)果(pt,i,tag)。若查找成功,則特征值</p><p> // tag=1,指針pt所指結(jié)點中第i個關(guān)鍵字等于K;否則特征值tag=0,等于K的</p><p> // 關(guān)鍵字應插
36、入在指針Pt所指結(jié)點中第i和第i+1個關(guān)鍵字之間。</p><p><b> {</b></p><p><b> Result r;</b></p><p><b> int i=1;</b></p><p> BTree p=T,q=NULL;
37、 // 初始化,p指向待查結(jié)點,q指向p的雙親</p><p> int found=FALSE;</p><p> while(p && !found){</p><p> i=Search( p, k); //在p->key[1...keynum]中查找</p>
38、<p> if(i && p->key[i]==k) found=TRUE; //找到待查關(guān)鍵字</p><p><b> else</b></p><p><b> {</b></p><p><b> q=p;</b></p>
39、<p> p=p->ptr[i];</p><p><b> }</b></p><p><b> }</b></p><p> if(found) </p><p><b> {</b></p><p><b>
40、; r.pt=p;</b></p><p><b> r.i=i;</b></p><p><b> r.tag=1;</b></p><p><b> }</b></p><p><b> else</b></p>&
41、lt;p><b> {</b></p><p><b> r.pt=q;</b></p><p><b> r.i=i;</b></p><p> r.tag=0; </p><p><b> }</b></p>&l
42、t;p> return r; </p><p><b> }</b></p><p> voidInsert(BTree &q, inti, int k, BTree ap, Record *recptr)</p><p> // 將k和ap分別插入到q->key[i+1]和q->ptr[i+1],并插入關(guān)
43、鍵字為k的記錄recprt</p><p><b> {</b></p><p> for(int j=q->keynum;j>i;--j)</p><p> { // 記錄、關(guān)鍵字、子樹指針后移</p><p> q-&
44、gt;key[j+1]=q->key[j];</p><p> q->ptr[j+1]=q->ptr[j];</p><p> q->recptr[j+1]=q->recptr[j];</p><p><b> }</b></p><p> q->key[i+1]=k;
45、 //插入記錄、關(guān)鍵字、子樹指針,關(guān)鍵字個數(shù)加1</p><p> q->ptr[i+1]=ap;</p><p> q->recptr[i+1]=recptr;</p><p> q->keynum++;</p><p> if(ap) ap->parent = q;
46、 //子樹ap的父親指針</p><p><b> }</b></p><p> voidSplit(BTree&q, int n, BTree &ap)</p><p> // 以n為分界將結(jié)點q分裂為兩個結(jié)點,前一半保留,后一半移入新生結(jié)點ap</p><p
47、><b> {</b></p><p><b> inti;</b></p><p> ap = (BTree)malloc(sizeof(BTNode)); // 申請新結(jié)點ap</p><p> ap->ptr[0]=q->ptr[n]; </p>
48、<p> for(i = n+1;i <= m; i++) // n后的關(guān)鍵字、子樹指針、記錄轉(zhuǎn)移到ap</p><p><b> {</b></p><p> ap->key[i-n] = q->key[i];</p><p> ap->ptr[i-n] = q->ptr[i];&
49、lt;/p><p> ap->recptr[i-n] = q->recptr[i];</p><p><b> }</b></p><p> ap->keynum = q->keynum - n; // 計算ap的關(guān)鍵字個數(shù)</p><p> q->keynum = n-1
50、; // q的關(guān)鍵字個數(shù)減少</p><p> ap->parent = q->parent;</p><p> for (i=0; i<=m-n; i++) </p><p> if(ap->ptr[i]) ap->ptr[i]->parent = ap; /
51、/ ap的子樹的父親指針</p><p><b> }</b></p><p> void NewRoot(BTree &T, BTree p, int k, BTree ap,Record *recptr)</p><p> // 當插入B樹時T為空或根結(jié)點分裂為p和ap兩個節(jié)點,需建立一個根節(jié)點空間</p>&l
52、t;p> // 本函數(shù)為T申請一塊空間,插入p,k,ap和記錄rec</p><p><b> {</b></p><p> T = (BTree)malloc(sizeof(BTNode));</p><p> T->keynum = 1;</p><p> T->ptr[0]
53、= p; // 插入</p><p> T->ptr[1] = ap; </p><p> T->key[1] = k;</p><p> T->recptr[1] = recptr;</p><p> if (p) p->parent= T; // T
54、的子樹ap的父親指針</p><p> if (ap) ap->parent = T;</p><p> T->parent = NULL; // 根節(jié)點雙親為NULL</p><p><b> }</b></p><p> int InsertBTree(BTree &T,
55、 int k, BTree q, int i,Record *recptr) </p><p> // 在m階B樹T上結(jié)點*q的key[i]與key[i+1]之間插入關(guān)鍵字K和記錄rec。</p><p> // 若引起結(jié)點過大,則沿雙親鏈進行必要的結(jié)點分裂調(diào)整,使T仍是m階B樹。</p><p><b> {</b></p&g
56、t;<p> BTree ap = NULL;</p><p> int finished = FALSE; // T是空樹,生成僅含關(guān)鍵字K的根結(jié)點*T</p><p> if (!q) NewRoot(T, NULL, k, NULL,recptr);</p><p><b> else{&l
57、t;/b></p><p> while (!finished) </p><p><b> {</b></p><p> Insert(q, i, k, ap,recptr);/將k和ap插入到q->key[i+1]和q->ptr[i+1]</p><p> if (q->keyn
58、um < m) finished = TRUE; // 插入完成</p><p><b> else{</b></p><p> Split(q, (m+1)/2, ap); // 分裂結(jié)點q</p><p> k = q->key[(m+1)/2];</p&
59、gt;<p> recptr = q->recptr[(m+1)/2];</p><p> if (q->parent) </p><p> { // 在雙親結(jié)點*q中查找k的插入位置</p><p> q = q->parent; </p><p> i = Search(q, k);
60、 </p><p><b> } </b></p><p> else finished = OVERFLOW; // 根節(jié)點已分裂為*q和*ap兩個結(jié)點</p><p><b> } </b></p><p><b> } </b></p>&
61、lt;p> if (finished == OVERFLOW)// 根結(jié)點已分裂為結(jié)點*q和*ap</p><p> NewRoot(T, q, k, ap,recptr);// 需生成新根結(jié)點*T,q和ap為子樹指針</p><p><b> }</b></p><p> return OK;</p>
62、<p><b> }</b></p><p> voidTakePlace(BTree &q, int &i)</p><p> // *q結(jié)點的第i個關(guān)鍵字為k,用q的后繼關(guān)鍵字替代q,且令q指向后繼所在結(jié)點</p><p><b> {</b></p><p&g
63、t; BTree p = q;</p><p> q = q->ptr[i];</p><p> while(q->ptr[0]) q = q->ptr[0]; // 查找p的后繼</p><p> p->key[i] = q->key[1]; // 關(guān)鍵字代替</p>
64、<p> p->recptr[i] = q->recptr[1]; // 記錄代替</p><p> i = 1;// 代替后應該刪除q所指結(jié)點的第1個關(guān)鍵字</p><p><b> }</b></p><p> voidDel(BTree q, int i)</p
65、><p> // 刪除q所指結(jié)點第i個關(guān)鍵字及其記錄</p><p><b> {</b></p><p> for(;i < q->keynum ;i++)// 關(guān)鍵字和記錄指針前移</p><p><b> {</b></p><p> q-&
66、gt;key[i] = q->key[i+1];</p><p> q->recptr[i] = q->recptr[i+1];</p><p><b> }</b></p><p> q->keynum --;// 關(guān)鍵字數(shù)目減1</p><p><b> }&
67、lt;/b></p><p> intBorrow(BTree q)</p><p> // 若q的兄弟結(jié)點關(guān)鍵字大于(m-1)/2,則從兄弟結(jié)點上移最?。ɑ蜃畲螅┑年P(guān)鍵字到雙親結(jié)點,</p><p> // 而將雙親結(jié)點中小于(或大于)且緊靠該關(guān)鍵字的關(guān)鍵字下移至q中,并返回OK,否則返回EREOR。</p><p><
68、b> {</b></p><p><b> inti;</b></p><p> BTreep = q->parent, b;// p指向q的雙親結(jié)點</p><p> for(i = 0 ; p->ptr[i] != q;i++) ; // 查找q在雙親p的子樹位置</p&g
69、t;<p> if(i >= 0 && i+1 <= p->keynum && p->ptr[i+1]->keynum > (m-1)/2)</p><p> {// 若q的右兄弟關(guān)鍵字個數(shù)大于(m-1)/2</p><p> b = p->ptr[i+1];// b
70、指向右兄弟結(jié)點</p><p> q->ptr[1] = b->ptr[0];// 子樹指針也要同步移動</p><p> q->key[1] = p->key[i+1];// 從父節(jié)點借第i+1個關(guān)鍵字</p><p> q->recptr[1] = p->recptr[i+1];</p>
71、<p> p->key[i+1] = b->key[1];// b第一個關(guān)鍵字上移到父節(jié)點</p><p> p->recptr[i+1] = b->recptr[1];</p><p> for(i =1 ;i <= b->keynum;i++)// b第一個關(guān)鍵字上移,需把剩余記錄前移一位</p><p&
72、gt;<b> {</b></p><p> b->key[i] = b->key[i+1];</p><p> b->recptr[i] = b->recptr[i+1];</p><p> b->ptr[i-1] = b->ptr[i];</p><p><b>
73、 }</b></p><p><b> }</b></p><p> else if(i > 0 && p->ptr[i-1]->keynum > (m-1)/2)</p><p> {// 若q的左兄弟關(guān)鍵字個數(shù)大約(m-1)/2</p><p
74、> b = p->ptr[i-1];// b指向左兄弟結(jié)點</p><p> q->ptr[1] = q->ptr[0];</p><p> q->ptr[0] = b->ptr[b->keynum];</p><p> q->key[1] = p->key[i];// 從父節(jié)
75、點借第i個關(guān)鍵字</p><p> q->recptr[1] = p->recptr[i];</p><p> p->key[i] = b->key[b->keynum];// 將b最后一個關(guān)鍵字上移到父節(jié)點</p><p> p->recptr[i] = b->recptr[b->keynum];<
76、/p><p><b> }</b></p><p> else return ERROR;// 無關(guān)鍵字大于(m-1)/2的兄弟</p><p> q->keynum ++;</p><p> b->keynum --;</p><p> for(i = 0 ;i
77、<=q->keynum; i++)</p><p> if(q->ptr[i]) q->ptr[i]->parent = q; // 刷新q的子結(jié)點的雙親指針</p><p> return OK;</p><p><b> }</b></p><p> void
78、Combine(BTree &q)</p><p> // 將q剩余部分和q的父結(jié)點的相關(guān)關(guān)鍵字合并到q兄弟中,然后釋放q,令q指向修改的兄弟</p><p><b> {</b></p><p> inti, j ;</p><p> BTree p = q->parent, b;
79、// p指向q的父親</p><p> for(i = 0; p->ptr[i] != q; i++) ;// 插好q在父親p中的子樹位置</p><p> if(i == 0)// 如為0,則需合并為兄弟的第一個關(guān)鍵字</p><p><b> {</b></p><p> b =
80、p->ptr[i+1];</p><p> for(j = b->keynum ; j >= 0 ;j--)// 將b的關(guān)鍵字和記錄后移一位</p><p><b> {</b></p><p> b->key[j+1] = b->key[j];</p><p> b->r
81、ecptr[j+1] = b->recptr[j];</p><p> b->ptr[j+1] = b->ptr[j];</p><p><b> }</b></p><p> b->ptr[0] = q->ptr[0]; // 合并</p><p>
82、b->key[1] = p->key[1];</p><p> b->recptr[1] = p->recptr[1];</p><p><b> }</b></p><p> else if(i > 0)// 若q在父親的子樹位置大約0</p><p> {
83、// 需合并為兄弟b的最后一個關(guān)鍵字</p><p> b = p->ptr[i-1];</p><p> b->key[b->keynum+1] = p->key[i]; // 合并</p><p> b->recptr[b->keynum+1] = p->recptr[i];&l
84、t;/p><p> b->ptr[b->keynum+1] = q->ptr[0];</p><p><b> }</b></p><p> if(i == 0 || i == 1)// 若i為0或1,需將父節(jié)點p關(guān)鍵字前移一位</p><p> for( ; i < p->k
85、eynum; i++)</p><p><b> {</b></p><p> p->key[i] = p->key[i+1];</p><p> p->ptr[i] = p->ptr[i+1];</p><p> p->recptr[i] = p->recptr[i+1];&
86、lt;/p><p><b> }</b></p><p> p->keynum --;</p><p> b->keynum ++;</p><p><b> free(q);</b></p><p> q = b;// q指向修改的兄弟
87、結(jié)點</p><p> for(i = 0;i <= b->keynum; i++)</p><p> if(b->ptr[i]) b->ptr[i]->parent = b; // 刷新b的子結(jié)點的雙親指針</p><p><b> }</b></p><p> i
88、ntDeleteBTree(BTree &T,int k)</p><p> // 在m階B樹T上刪除關(guān)鍵字k及其對應記錄,并返回OK。</p><p> // 如T上不存在關(guān)鍵字k,則返回ERROR。</p><p><b> {</b></p><p><b> intx=k;</
89、b></p><p> BTreeq,b = NULL;</p><p> intfinished = FALSE,i = 1;</p><p> Result res = SearchBTree(T,k);// 在T中查找關(guān)鍵字k</p><p> if(res.tag == 0 ) return ERROR;
90、// 未搜索到</p><p><b> else</b></p><p><b> {</b></p><p> q = res.pt;// q指向待刪結(jié)點</p><p> i = res.i;</p><p> if(q->pt
91、r[0]) TakePlace(q, i); // 若q的子樹不空,(非底層結(jié)點)</p><p> // 則以其后繼代之,且令q指向后繼所在結(jié)點</p><p> Del(q,i);// 刪除q所指向結(jié)點中第i個關(guān)鍵字及記錄</p><p> if(q->keynum>=(m-1)/2||!q->parent)//
92、 若刪除后關(guān)鍵字個數(shù)不小于(m-1)/2或q是根 </p><p><b> {</b></p><p> finished = TRUE;// 刪除完成</p><p> if(q->keynum == 0 ) T = NULL;// 若q的關(guān)鍵字個數(shù)為0
93、 ,則為空樹</p><p><b> }</b></p><p> while(!finished)</p><p><b> {</b></p><p> if(Borrow(q))finished = TRUE;// 若q的相鄰兄弟結(jié)點關(guān)鍵字大于(m-1)/2,則
94、 </p><p> //從該兄弟結(jié)點上移一個最大(或最?。╆P(guān)鍵字到</p><p> // 父節(jié)點,從父節(jié)點借一關(guān)鍵字到q</p><p> else{// 若q相鄰兄弟關(guān)鍵字個數(shù)均等于┌m /2┑-1</p><p> Combine(q);// 將q中的剩余部分和雙親中的相關(guān)關(guān)鍵字合并至q的一個兄弟中<
95、/p><p> q = q->parent;// 檢查雙親</p><p> if(q == T && T->keynum ==0 )// 若被刪結(jié)點的父節(jié)點是根T且T的關(guān)鍵字個數(shù)為0</p><p><b> {</b></p><p> T = T->ptr[0];
96、// 新根</p><p> T->parent = NULL;</p><p> free(q);// 刪除原雙親結(jié)點</p><p> finished = TRUE;</p><p><b> }</b></p><p> else if(q-&g
97、t;keynum >= m/2) finished = TRUE;</p><p> }// 合并后雙親關(guān)鍵字個數(shù)不少于(m-1)/2,完成</p><p><b> }</b></p><p><b> }</b></p><p> return OK ;</p>
98、;<p><b> }</b></p><p> voidBTreeTraverse(BTree T,void ( *Visit)(BTree p))</p><p> // 遍歷B樹T,對每個結(jié)點調(diào)用Visit函數(shù)</p><p><b> {</b></p><p>
99、if(!T) return;</p><p><b> Visit(T);</b></p><p> for(int i=0;i<=T->keynum;++i)</p><p> if(T->ptr[i])BTreeTraverse(T->ptr[i],Visit);</p><p><
100、;b> }</b></p><p> voidShowBTree(BTree T,short x = 8)</p><p> // 遞歸以凹入表形式顯示B樹T,每層的縮進量為x,初始縮進量為8</p><p><b> {</b></p><p> if(!T)return ;</
101、p><p><b> inti;</b></p><p> printf("\n");</p><p> for(i = 0;i<=x;i++) putchar(' '); // 縮進x</p><p> for(i = 1 ;i <= T->
102、keynum;i++)</p><p> printf("%d,",T->key[i]);</p><p> for(i = 0 ;i <= T->keynum;i++)// 遞歸顯示子樹結(jié)點關(guān)鍵字</p><p> ShowBTree(T->ptr[i],x+7);</p><p&
103、gt;<b> } </b></p><p> /****************************圖書管理存儲定義*******************************/</p><p> typedefstructReaderNode // 借閱者</p><p><b> {
104、 </b></p><p> intcardnum; // 證號</p><p> charrname[MAX_NAME_LEN]; // 姓名</p><p><b> union{</b></p><p> struct{
105、</p><p> tmbordate; // 借書日期</p><p> tmretdate; // 還書日期</p><p><b> };</b></p><p><b> };</b></p><p>
106、 }ReaderNode,*ReaderType; // 讀者類型</p><p> typedefstructBookNode// 圖書結(jié)點</p><p><b> {</b></p><p> intbooknum;// 書號</p><p>
107、 charbookname[MAX_BKNAME_LEN];// 書名</p><p> charwriter[MAX_NAME_LEN]; // 作者名</p><p> intcurrent; // 現(xiàn)存量</p><p> int total;
108、 // 總庫存</p><p> ReaderTypereader;// 借閱者鏈表指針</p><p> } BookNode,*BookType;// 圖書類型</p><p> /*************************************************************
109、****************/</p><p> /*****************************圖書管理函數(shù)定義********************************/ </p><p> voidInitLibrary(BTree &L )</p><p> // 初始化書庫L為空書庫。</p><p
110、><b> {</b></p><p><b> L = NULL;</b></p><p><b> }</b></p><p> voidInsertBook(BTree &L ,BookType B , Result res)</p><p>
111、// 書庫L已存在,res包含B書在書庫L中的位置或應該插入的位置</p><p> // 如果書庫中已存在B書,則只將B書的庫存量增加,否則插入B書到書庫L中。</p><p><b> {</b></p><p> if(res.tag==0) InsertBTree(L, B->booknum, res.pt, res.i,
112、B); // 書庫中不存在該書,則插入</p><p><b> else</b></p><p><b> {</b></p><p> BookType b=res.pt->recptr[res.i];</p><p> b->current=b->current+B-
113、>total; //現(xiàn)存量增加</p><p> b->total=b->total+B->total; //總庫存增加</p><p><b> }</b></p><p><b> }</b&g
114、t;</p><p> intDeleteBook(BTree &L ,BookType B)</p><p> // 如果書庫中存在B書,則從書庫中刪除B書的信息,并返回OK,否則返回ERROR</p><p><b> {</b></p><p> if(DeleteBTree(L,B->bo
115、oknum)) return OK; //刪除成功</p><p> else return ERROR; //刪除失敗 </p><p><b> }</b></p><p> intCanBorrow(BTree L,BookType B
116、 ,ReaderType R)</p><p> // 書庫L中存在B書。若B書現(xiàn)存量大于0,則可出借返回TRUE</p><p> // 不能出借返回FALSE。</p><p><b> {</b></p><p> if(B->current>0) return TRUE;
117、 //現(xiàn)存量大于零 else return FALSE; //其他情況均不允許出借</p><p><b> }</b></p><p> voidBorrowBook(BTree L ,BookType B ,
118、ReaderType R)</p><p> // 書庫L存在,B書是書庫中的書并且可被讀者借閱</p><p> // 借出一本B書,登記借閱者基本信息。</p><p><b> {</b></p><p> ReaderType r,pre;</p><p> GetDate(R
119、->bordate); // 獲取系統(tǒng)當前時間為借書時間日期</p><p> AddDate(R->retdate,R->bordate,KEEP_DAYS); //當前時間加上90天為還書日期</p><p> if(!B->reader)B->reader=R; //暫無借
120、閱者,直接登記</p><p><b> else</b></p><p><b> {</b></p><p> for(pre=r=B->reader;r;pre=r,r=r->nextr);</p><p> pre->nextr=R;
121、 //登記至借閱者表尾</p><p><b> }</b></p><p> B->current--;</p><p><b> }</b></p><p> int ReturnBook(BTree L ,int booknum ,int
122、cardnum,BookType &B ,ReaderType &R)</p><p> // booknum為還書書號,cardnum為還書者借閱證號,</p><p> // 若書庫中不存在書號為booknum的書,則搜索出錯,返回-1</p><p> // 若有借閱記錄,則注銷該記錄,并用B和R返回圖書信息和借閱者信息并返回1,<
123、/p><p> // 若沒有r、借閱的記錄,則用B返回圖書信息,并返回0</p><p><b> {</b></p><p> Result res=SearchBTree(L,booknum); //在B樹按書號搜索</p><p> if(res.tag==0) return -1;
124、 </p><p> B = res.pt->recptr[res.i];// 用B記錄圖書信息</p><p> ReaderTypep=res.pt->recptr[res.i]->reader,pre=p;</p><p> while(p){ // 搜索借書者鏈
125、表</p><p> if(pre==p&&p->cardnum == cardnum)//只有一個借書者</p><p><b> {</b></p><p><b> R = p;</b></p><p> B->current++;
126、 // 現(xiàn)存量增1</p><p><b> return 1;</b></p><p><b> }</b></p><p> if(p->cardnum==cardnum) //多個借書者</p><p><b> { &l
127、t;/b></p><p><b> R = p;</b></p><p> pre ->nextr = p->nextr;</p><p> B->current++; // 現(xiàn)存量增1</p><p><b> return 1;</b><
128、;/p><p><b> }</b></p><p><b> pre=p;</b></p><p> p=p->nextr;</p><p><b> }</b></p><p><b> return 0;</b>&
129、lt;/p><p><b> }</b></p><p> void PrintH() //表格頭部格式</p><p><b> {</b></p><p> printf("\n"
130、;);</p><p> printf("║********************圖書基本信息****************************║\n");</p><p> printf("║ 書號 │ 書名 │ 著者 │現(xiàn)存│總庫存│出版年份│定價 ║\n"); </p><p><b>
131、 }</b></p><p> void PrintD(BookType B) //顯示B書基本信息</p><p><b> {</b></p><p> printf("║───┼────┼────┼──┼───┼────┼───║\n&q
132、uot;);</p><p> printf("║ %-4d │ %-20s│ %-11s│%-4d│ %-4d │%-6d │%-6.1f║",B->booknum,B->bookname,B->writer,B->current,B->total,B->publishyear,B->price);</p><p>&l
133、t;b> }</b></p><p> void PrintT() //表格底部格式</p><p><b> {</b></p><p> printf("\n║───┼─────┼───┼──┼───┼───
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 《數(shù)據(jù)結(jié)構(gòu)》課程設(shè)計---圖書管理系統(tǒng)
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計--圖書管理系統(tǒng)
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計---圖書管理系統(tǒng)
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計-圖書管理系統(tǒng)
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計-圖書管理
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計--圖書管理
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計報告——圖書管理系統(tǒng)
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計圖書管理系統(tǒng)
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計報告圖書管理系統(tǒng)
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計圖書管理系統(tǒng)
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計報告--學院圖書管理系統(tǒng)
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計——圖書管理信息系統(tǒng)
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計圖書管理系統(tǒng)實驗報告
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計報告---- 圖書管理系統(tǒng)的設(shè)計與實現(xiàn)
- 數(shù)據(jù)結(jié)構(gòu)-圖書管理系統(tǒng)
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計--圖書借閱管理系統(tǒng)
- 圖書管理系統(tǒng)(含源代碼)c語言_數(shù)據(jù)結(jié)構(gòu)課程設(shè)計報告
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計----用c++語言實現(xiàn)圖書管理系統(tǒng)
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計--圖書館管理系統(tǒng)
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計--小型圖書購銷管理系統(tǒng)
評論
0/150
提交評論