版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、實(shí)用標(biāo)準(zhǔn)文案課程設(shè)計(jì)報(bào)告課程名稱數(shù)據(jù)結(jié)構(gòu)課題名稱排序綜合專 業(yè)班 級(jí)學(xué) 號(hào)姓 名聯(lián)系方式指導(dǎo)教師20 11 年12 月 21 日目 錄1 .問題陳述 32 .設(shè)計(jì)方法闡述 32.1 總體規(guī)劃 32.2 功能構(gòu)想 42.2.1 增加成員 42.2.2 修改成員資料 52.2.3 刪除成員 62.2.4 打開家譜 72.2.5 新建家譜 82.2.6 保存家譜 102.2.7 查看某代信息 112.2.8 按姓名查找 122.2.9 按生日查找 122.2.10 查看成員關(guān)系 132.2.11 按出生日期排序 142.3 板塊整合 152.4 調(diào)試分析 193 .總結(jié) 194 .測(cè)試結(jié)果 201
2、.問題陳述家譜用于記錄某家族歷代家族成員的情況與關(guān)系?,F(xiàn)編制一個(gè)家譜資料管理軟件,實(shí) 現(xiàn)對(duì)一個(gè)家族所有的資料進(jìn)行收集整理。支持對(duì)家譜的存儲(chǔ)、更新、查詢、統(tǒng)計(jì)等操作。并 用計(jì)算機(jī)永久儲(chǔ)存家族數(shù)據(jù),方便隨時(shí)調(diào)用。2 .設(shè)計(jì)方法闡述2.1 總體規(guī)劃在動(dòng)手編制程序之前,先要做好程序的規(guī)劃,包括程序儲(chǔ)存數(shù)據(jù)所用的結(jié)構(gòu),數(shù)據(jù)類型等等,只有確定了數(shù)據(jù)類型和數(shù)據(jù)結(jié)構(gòu),才能在此基礎(chǔ)上進(jìn)行各種算法的設(shè)計(jì)和程序的編寫。首先是考慮數(shù)據(jù)類型。在家譜中,家族成員是最基本的組成部分,對(duì)于家族管理中,已經(jīng)不能再進(jìn)行細(xì)分了,所以選定家族成員作為數(shù)據(jù)的基本類型,并在程序中定義COperationFamilytree 類。其中 C
3、OperationFamilytree類的各種屬性可以根據(jù)需要進(jìn)行添加或刪除,從日常生活應(yīng)用的角度出發(fā),制定了 COperationFamilytree 類中包含了一下 屬性:char nameMAX_CHARNUM;/ 姓名Date birthday;出生日期In tsex; 性另1Jchar addrMAX_CHARNUM;基本資料int live;健在否Date deathday;死亡日期int ChildNums(Person pNode); 返回 pNode孩子數(shù)intInSiblingPos(Person pNode); 返回 pNode在其兄弟中的排行為方便計(jì)算機(jī)進(jìn)行比較,在fa
4、milytree類的某些屬性中用數(shù)字代替了某些不會(huì)改變的字 符串,譬如性別(1代表男,0代表女)、判斷是否健在(1為是,0為否)。在設(shè)置日期上, 為方便以后的計(jì)算與比較,也將日期用整型數(shù)字表示19990505表示1999年5月5日,這種表示方法只需在輸入和輸出上作少許的運(yùn)算便可方便地與日期進(jìn)行轉(zhuǎn)換。在家族關(guān)系的表示上,并沒有用相關(guān)家屬的姓名作為儲(chǔ)存數(shù)據(jù),而僅僅是存儲(chǔ)了各關(guān)系親屬的ID,方便日后作為指針指示調(diào)用相對(duì)應(yīng)的家族成員。其中在屬性pNode上,其表示的是下一個(gè)同父母的弟或妹ID,也就是說,當(dāng)某家族成員有若干個(gè)子女,其pNode僅指向第一個(gè)孩子,其余的孩子如何表示呢?可以通過第一個(gè)孩子的p
5、Node指示,如此類推,直到孩子的pNode =0為止。這樣就可以避免需在程序設(shè)計(jì)時(shí)預(yù)定父母可以擁有的孩子數(shù),有多少孩子就表示多少, 實(shí)現(xiàn)了動(dòng)態(tài)的儲(chǔ)存數(shù)據(jù)。在選擇數(shù)據(jù)結(jié)構(gòu)方面,從直觀來說,選擇樹型結(jié)構(gòu)通過鏈表來連接數(shù)據(jù)無疑是最直觀易懂的,我在一開始構(gòu)思的時(shí)候也是從樹型結(jié)構(gòu)去想的,但當(dāng)構(gòu)思到如何存儲(chǔ)和提取數(shù)據(jù)是,便發(fā)現(xiàn)了問題。毫無疑問,用指針來處理數(shù)據(jù)的確是方便直觀,但當(dāng)我要儲(chǔ)存數(shù)據(jù)是,便發(fā)現(xiàn)把指針儲(chǔ)存進(jìn)去是沒有作用的,因?yàn)楫?dāng)我們下一次讀取數(shù)據(jù)的時(shí)候,數(shù)據(jù)內(nèi)存地址已經(jīng)不同了,不在是我們上次存儲(chǔ)數(shù)據(jù)時(shí)的地址,也就是說指針這時(shí)已經(jīng)是沒有作用了。要解決這樣的問題,我們必須要在存儲(chǔ)數(shù)據(jù)之前,先家族樹序列
6、化,用數(shù)組 (或者其他可以用數(shù)字表示關(guān)系的方法)來存儲(chǔ),并且,再下一次讀取數(shù)據(jù)時(shí),再把數(shù)據(jù)按照序列號(hào)重新組成一個(gè)家 族樹,過程比較繁復(fù),而且實(shí)現(xiàn)起來也不容易。所以我便考慮直接用數(shù)組來存儲(chǔ)數(shù)據(jù),即使是在內(nèi)存中也用數(shù)組來處理數(shù)據(jù)間的聯(lián)系。運(yùn)用順序表這個(gè)結(jié)構(gòu)雖然不是那么直觀,但在查找數(shù)據(jù)時(shí)的算法設(shè)計(jì)比較簡單容易實(shí)現(xiàn),效率高,而且在內(nèi)存中的數(shù)據(jù)可以直接讀入到文件中,文件中的數(shù)據(jù)也可以直接讀入內(nèi)存,不需要進(jìn)行轉(zhuǎn)換。所以在衡量的各個(gè)方面之后,我決定用數(shù)組來處理數(shù)據(jù)間的聯(lián)系。2.2 功能構(gòu)想構(gòu)想好總體規(guī)劃之后,便開始設(shè)計(jì)程序中需要用到的各個(gè)功能函數(shù),初步構(gòu)想是要先 實(shí)現(xiàn)最基本的幾項(xiàng)功能,其中數(shù)據(jù)操作的有:增
7、加成員,修改成員資料,刪除成員;數(shù)據(jù)存 取的有:打開家譜,新建家譜,保存家譜,另存家譜;數(shù)據(jù)查詢的有:查看某代信息,按姓 名查找,按生日查找,查看成員關(guān)系,按出生日期排序等等。2.2.1 增加成員這項(xiàng)功能做得不夠理想,在規(guī)劃時(shí)沒有把成員以配偶的形式增加,而只能以子女的形 式增加。對(duì)應(yīng)的函數(shù)代碼如下:void COperationFamilytree:Add(Person parent, Person addNode)本函數(shù)把a(bǔ)ddNode結(jié)點(diǎn)加入到其父結(jié)點(diǎn) addNode->child=addNode->sibling=0;addNode->parent=parent;add
8、Node結(jié)點(diǎn)的父指針域應(yīng)指向parentif(parent=0)根結(jié)點(diǎn)if(T=0) T=addNode; return; addNode->child=T;T->parent=addNode;T=addNode; return;if(parent->child=0) parent->child=addNode;elseInsertSibling(parent->child,addNode); 2.2.2修改成員資料parent 下把欲加入的結(jié)點(diǎn)所有指針域置空因addNode欲加為 parent的孩子,故/若parent為0,則表示欲加 addNode為/若本為空
9、家譜把a(bǔ)ddNode當(dāng)成根結(jié)點(diǎn)使原來的根結(jié)點(diǎn)成為新根結(jié)點(diǎn)的孩子/parent無孩子,把a(bǔ)ddNode加入其孩子把a(bǔ)ddNode加到parent孩子的兄弟域中修改成員這項(xiàng)功能實(shí)現(xiàn)起來比較簡單,找到要修改成員的名字,再輸入新修改的值, 整個(gè)函數(shù)沒有什么需要運(yùn)用算法的地方,但如果想真正寫好這個(gè)函數(shù),則需要考慮相當(dāng)多的細(xì)節(jié),譬如各個(gè)輸入項(xiàng)目的錯(cuò)誤處理等等,要非常全面地考慮各項(xiàng)細(xì)節(jié)。函數(shù)代碼如下:void CFamilytreeDlg:OnModify()/ TODO: Add your command handler code hereif(operFamilytree.GetRoot()=0)ret
10、urn;CModifyInfoDlg dlg;HTREEITEM hItem;hItem=m_peTree.GetSelectedItem();dlg.m_newname=m_peTree.GetItemText(hItem);Person oneself=0;char oldnameMAX_CHARNUM;strcpy(oldname,dlg.m_newname);operFamilytree.Find(operFamilytree.GetRoot(),oneself,oldname);if(dlg.DoModal()=IDCANCEL) return;UpdateData(FALSE);P
11、erson newValue=new PersonNode;strcpy(newValue->,dlg.m_newname);判斷家譜中是否已有用戶給定的新名字if(strcmp(newValue->,oldname)=0);用戶不修改姓名else Person p=0; operFamilytree.Find(operFamilytree.GetRoot(),p,newValue->); 查找 家譜中有沒有此人if(p!=0)AfxMessageBox("家譜中已有此人!");delete newVa
12、lue; return; strcpy(newValue->info.addr,dlg.m_newaddr); newValue->info.marry=dlg.m_marry;newValue->info.live=dlg.m_live;newValue->info.birthday.day=dlg.m_birthday_day;newValue->info.birthday.month=dlg.m_birthday_month;newValue->info.birthday.year=dlg.m_birthday_year;if(!newValue-&g
13、t;info.live)如若過世,則應(yīng)有死亡日期newValue->info.deathday.day=dlg.m_deathday_day;newValue->info.deathday.month=dlg.m_deathday_month; newValue->info.deathday.year=dlg.m_deathday_year;if(!operFamilytree.IsDateValid(newValue->info.deathday) AfxMessageBox("此人信息中死亡日期不合實(shí)際!");delete newValue; r
14、eturn; if(operFamilytree.CompareDate(newValue->info.deathday,newValue->info.birthday)=- 1)AfxMessageBox("此人死亡日期不可能比其出生日期早!");return; operFamilytree.Modify(oneself,newValue); RefreshTree(); RefreshList(); IsFamilytreeModified=true;/ 置家譜修改標(biāo)記為真delete newValue; 2.2.3刪除成員用數(shù)組來儲(chǔ)存數(shù)據(jù),最麻煩的就是刪除
15、數(shù)組元素了,在這個(gè)程序中,刪除數(shù)組不但意 味著要重新排列各成員,還要重新更新各成員的關(guān)系,所以我個(gè)人認(rèn)為在這個(gè)程序中,刪除成員函數(shù)可以說是一個(gè)難點(diǎn)。通過分析,發(fā)現(xiàn)刪除成員的情況就只有兩種,只要針對(duì)這兩種情況處理好刪除,就可以完成成員刪除這個(gè)功能。1,刪除的成員是出于家族中最底層的,也就是刪除該成員不會(huì)牽連其他成員,但這也需要處理好其父母的孩子數(shù)。2 ,刪除的成員還有子孫,則需要連帶所有子孫都要?jiǎng)h除出家譜。遇到這種情況,不但要像上一種情況那樣處理父母和兄弟姐妹的關(guān)系,還要記錄牽連刪除的總?cè)藬?shù),因?yàn)閯h除不再是簡單刪除了一個(gè)人,而是若干個(gè),通過遞歸調(diào)用,可以統(tǒng)計(jì)出需要?jiǎng)h除的數(shù)目刪除函數(shù)的相關(guān)代碼如下
16、:void COperationFamilytree:Delete(Person &rootNode) 本函數(shù)刪除以rootNode為根結(jié)點(diǎn)的所有結(jié)點(diǎn) if(rootNode->parent)如果 rootNode 有父結(jié)點(diǎn)if(rootNode->parent->child=rootNode)如果 rootNode 為其父結(jié)點(diǎn)的第一個(gè)孩子rootNode->parent->child=rootNode->sibling;因要?jiǎng)h掉rootNode,故把其父結(jié)點(diǎn)的孩子指針指向rootNode的第一個(gè)兄弟else如果rootNode不是父結(jié)點(diǎn)的第一個(gè)孩子
17、Person p=rootNode->parent->child;找至U rootNode 應(yīng)在兄弟中的位置for(;p->sibling!=rootNode;p=p->sibling) ; p->sibling=rootNode->sibling;插入到兄弟中PostOrderTraverse(rootNode->child,DestroyNode); 刪除以 rootNode->child 為根結(jié)點(diǎn) 的所有結(jié)點(diǎn) if(rootNode=T)刪除 rootNode 結(jié)點(diǎn)。如果rootNode為根結(jié)點(diǎn),則刪除根結(jié)點(diǎn)TDestroyNode(T);
18、 else DestroyNode(rootNode); 1.1.4 打開家譜打開家譜函數(shù)的相關(guān)代碼如下:int COperationFamilytree:ReadNode(FILE *fp, Person &T,char* parentname)本函數(shù)從文件fp中讀取信息到結(jié)點(diǎn) T中,并讀取結(jié)點(diǎn)的父親名字到字符數(shù)組parentname中/分別讀取結(jié)點(diǎn)值,為:姓名,出生日期(年,月,日),婚否,地址,健在否,(如過世,還有死亡日期)fscanf(fp,"%s%d%d%d%d%s%d",T->,&T->info.birthday.
19、year,&T->info.birth day.month,&T->info.birthday.day,&T->info.marry,T->info.addr,&T->info.live);if(T->info.live=0)fscanf(fp,"%d%d%d",&T->info.deathday.year,&T->info.deathday.month,&T->info.deathday.day);fscanf(fp,"%s",parentna
20、me);if(!IsDateValid(T->info.birthday)出生日期合法性檢查return FILE_DATA_NOT_PRACTICAL;if(T->info.live=0)/若過世,死亡日期合法性檢查 if (CompareDate(T->info.birthday,T->info.deathday)!=-1)return FILE_DATA_NOT_PRACTICAL;if(!IsDateValid(T->info.deathday)return FILE_DATA_NOT_PRACTICAL;return OK;1.1.5 新建家譜新建家譜函
21、數(shù)的相關(guān)代碼如下:void COperationFamilytree:NewFamilytree()本函數(shù)新建一空家譜DestroyFamilytree();刪除原有家譜T=0;int COperationFamilytree:CreateFamilytree(CString filename)本函數(shù)建立一新家譜DestroyFamilytree();建立一新家譜之前,清空原有家譜FILE* fp;if(fp=fopen(filename,"r")=0)return READ_FILE_ERROR;T=new PersonNode;if(!T)return NOT_ENOU
22、GH_MEMORY;T->child=0;T->sibling=0;T->parent=0;Person parentT, temp;char parentnameMAX_CHARNUM;打開文件filename定義根結(jié)點(diǎn)定義兩個(gè)臨時(shí)結(jié)點(diǎn)定義一個(gè)臨時(shí)字符串?dāng)?shù)組讀取根結(jié)點(diǎn)值,(姓名,出生日期(年,月,日工婚否,地址,健在否,(如過世,還有死亡日 期)int result;result=ReadNode(fp,T,parentname);if(result=FILE_DATA_NOT_PRACTICAL)delete T;/若不合法,刪除申請(qǐng)的堆空間T=0;return resu
23、lt; if(strcmp(T->,parentname)=0)明為空樹delete T;T=0;return PEDIGREE_EMPTY;temp=new PersonNode;if(!temp)DestroyFamilytree();return NOT_ENOUGH_MEMORY;根結(jié)點(diǎn)名字與其父親名字相同,說申請(qǐng)一結(jié)點(diǎn)申請(qǐng)失敗釋放申請(qǐng)空間 result=ReadNode(fp,temp,parentname);while(strcmp(temp->,parentname)&&strcmp(temp->info.na
24、me,"end")讀取信息結(jié)束的條件是兩個(gè)人的名字同為end/if(result=FILE_DATA_NOT_PRACTICAL)若數(shù)據(jù)不合法,釋放已申請(qǐng)空間,然后返回delete temp;DestroyFamilytree();return result;parentT=0;Find(T,parentT,parentname);找至U parentname 所在結(jié)點(diǎn) parentTif(parentT)如果 parentT 存在,說明 parentname在家譜中并且 parentname為temp的父親int cmp;cmp=CompareDate(temp->
25、info.birthday,parentT->info.birthday);if(cmp<0)若孩子出生日期比父親大,則不對(duì)delete temp;DestroyFamilytree();return FILE_DATA_NOT_PRACTICAL;/temp的父指針指向 parentT;/parentname已經(jīng)有孩子/parentname無孩子 則 temp 應(yīng)為/parentname的第個(gè)孩子parentname 止匕人temp->child=temp->sibling=0; temp->parent=parentT; if(parentT->chil
26、d)InsertSibling(parentT->child,temp); /if elseparentT->child=temp;/ifelse/parentT不存在,說明家譜中不存在返回出錯(cuò)信息申請(qǐng)一結(jié)點(diǎn)申請(qǐng)失敗 釋放申請(qǐng)空間繼續(xù)讀取數(shù)據(jù)DestroyFamilytree();result=ReadNode(fp,temp,parentname);/whilereturn FILE_DATA_ERROR; temp=new PersonNode; if(!temp) DestroyFamilytree(); return NOT_ENOUGH_MEMORY;if(temp)de
27、lete temp;fclose(fp);return OK;1.1.6 保存家譜保存家譜函數(shù)的相關(guān)代碼如下:int COperationFamilytree:SaveFamilytree(CString filename)本函數(shù)保存家譜到文件filename中FILE* fp;if(fp=fopen(filename,"w")=0)打開文件 filenamereturn WRITE_FILE_ERROR;PreOrderTraverse(fp,T,SaveNode);從根結(jié)點(diǎn)開始存儲(chǔ)家譜數(shù)據(jù)置家譜數(shù)據(jù)結(jié)束標(biāo)記(一結(jié)點(diǎn)的名字與其父結(jié)點(diǎn)的名字同為end)fprintf(fp,
28、"%s %d %d %d %d %s %d %s","end”,1999,12,2,1,"end",1,"end");fclose(fp);return OK;void COperationFamilytree:PreOrderTraverse(FILE* fp,Person &T, void(_cdecl*Visit)(FILE* fp,Person &)本函數(shù)把所有以T結(jié)點(diǎn)為根結(jié)點(diǎn)的結(jié)點(diǎn)值存到文件fp中if(T)(*Visit)(fp,T);PreOrderTraverse(fp,T->child,
29、Visit);PreOrderTraverse(fp,T->sibling,Visit);void SaveNode(FILE *fp, Person &pNode) 本函數(shù)向文件fp中存取一結(jié)點(diǎn)pNode char ch='n'if(pNode) fprintf(fp,"%s%d %d %d %d %s %d,pNode->,pNode->info.birthday.year, pNode->info.birthday.month,pNode->info.birthday.day,pNode->info.
30、marry, pNode->info.addr,pNode->info.live); if(pNode->info.live=0) fprintf(fp,"%d%d%d,pNode->info.deathday.year,pNode->info.deathday.month, pNode->info.deathday.day); if(pNode->parent) fprintf(fp," %s ",pNode->parent->); else fprintf(fp," %s&quo
31、t;,"-1"); fprintf(fp," %c",ch); 1.1.7 查看某代信息查看某代信息函數(shù)的相關(guān)代碼如下:int COperationFamilytree:InGenerationPos(Person pNode) 本函數(shù)返回pNode結(jié)點(diǎn)在第幾代int pos=1;Person p;p=pNode->parent;for(;p!=0;p=p->parent)pos+;return pos;1.1.8 按姓名查找按姓名查找函數(shù)的相關(guān)代碼如下:void COperationFamilytree:Find(Person& T
32、,Person& Tname,char* name)本函數(shù)以T為根結(jié)點(diǎn)開始,搜索結(jié)點(diǎn)信息中名字等于name的結(jié)點(diǎn)if(T)如果T存在/T結(jié)點(diǎn)姓名和name相同,把T結(jié)點(diǎn)指/對(duì)T的兄弟遞歸搜索/對(duì)T的孩子遞歸搜索if(strcmp(T->,name)=0) 針傳給TnameTname=T;elseFind(T->sibling,Tname,name);Find(T->child,Tname,name);1.1.9 按生日查找按生日查找函數(shù)的相關(guān)代碼如下:void COperationFamilytree:Find(Person &T, Pers
33、on*& Tname,int month, int day) 本函數(shù)以T為根結(jié)點(diǎn)開始,搜索結(jié)點(diǎn)信息中生日等于month,day的結(jié)點(diǎn),并把所有符合條件的結(jié)點(diǎn)指針值存入以Tname為起始地址的地址數(shù)組中if(T)/如果T存在if(T->info.birthday.month=month&&T->info.birthday.day=day)/T結(jié)點(diǎn)生日與所給相同,把T結(jié)點(diǎn)指針傳給 Tname,同時(shí)Tname指針前進(jìn)Person temp;temp=new PersonNode;temp=T;if(temp->info.birthday.month=mont
34、h&&temp->info.birthday.day=day) *Tname=temp;Tname+;temp=NULL;Find(T->child,Tname,month,day); 對(duì) T 的孩子遞歸搜索Find(T->sibling,Tname,month,day);/對(duì) T 的兄弟遞歸搜索 1.1.10 查看成員關(guān)系查看成員關(guān)系函數(shù)的相關(guān)代碼如下:void CFamilytreeDlg:OnFamilytreeRelations() / TODO: Add your command handler code hereCRelationsDlg dlg;
35、if(dlg.DoModal()=IDCANCEL)return;UpdateData(FALSE);int pos1,pos2;Person oneself=0;char name1MAX_CHARNUM,name2MAX_CHARNUM;strcpy(name1,dlg.m_firstname);operFamilytree.Find(operFamilytree.GetRoot(),oneself,name1); if(oneself)pos1=operFamilytree.InGenerationPos(oneself); elseAfxMessageBox("本家譜中找不到
36、"+CString(name1)+"!"); return;Person p,q;CString generation;generation+=oneself->;generation+="在家譜中的位置:"for(q=oneself,p=q->parent;p!=0;p=p->parent)generation+=q->;generation+= "->" q=p;generation+=q->;generation+="n
37、"oneself=0;strcpy(name2,dlg.m_secondname);operFamilytree.Find(operFamilytree.GetRoot(),oneself,name2); if(oneself)pos2=operFamilytree.InGenerationPos(oneself);elseAfxMessageBox("本家譜中找不到"+CString(name2)+"!"); return; generation+=oneself->;generation+="在家譜中的位置
38、:"for(q=oneself,p=q->parent;p!=0;p=p->parent)generation+=q->;generation+="-> "q=p;generation+=q->;generation+="nn"CString cmpResult;if(pos1>pos2)cmpResult.Format("%s 在第 d 代,s 在第 d 代,s 是 s 的晚 昌二name1,pos1,name2,pos2,name1,name2);else i
39、f(pos1<pos2)cmpResult.Format("%s 在第 d 代,%s 在第 d 代,s 是 s 的長 昌二name1,pos1,name2,pos2,name1,name2);elsecmpResult.Format("%s 與$ 同在第 %d 代.",name1,name2,pos2);generation+=cmpResult;AfxMessageBox(generation);1.1.11 按出生日期排序按出生日期排序函數(shù)的相關(guān)代碼如下:void COperationFamilytree:SortByBirthday(QuickSort
40、Node *order) 本函數(shù)對(duì)順序表 order以出生日期的大小排序int totalNums=0;QuickSortNode* startaddr=order;startaddr+;GetPersonNums(T,totalNums);CopyInfoFromBiTreeToArray(T,startaddr);QuickSort(order,1,totalNums);2.3 板塊整合以上的功能設(shè)計(jì)生成的各種函數(shù)文件僅是獨(dú)立的各個(gè)板塊,要將這些函數(shù)有機(jī)地聯(lián)系起來,才能形成可以應(yīng)用的程序,首先我用了一個(gè)DefineStruct.h聲明數(shù)據(jù)類型與各個(gè)應(yīng)用函數(shù),其代碼如下:根據(jù)家譜的特點(diǎn),采用
41、孩子-兄弟的二叉樹鏈表表示法(鏈表的基本單位為以結(jié)構(gòu)PersomNode表示的結(jié)點(diǎn)),各種操作以COperationFamilytree類來實(shí)現(xiàn)。以下是CoperationFamilytree類包含的數(shù)據(jù)成員及基本操作class COperationFamilytree 定義家族成員結(jié)構(gòu)public:COperationFamilytree();/構(gòu)造函數(shù)virtual COperationFamilytree();/析構(gòu)函數(shù)void NewFamilytree();/新建一空家譜int CreateFamilytree(CString filename);/從輸入文件filename 中讀取
42、數(shù)據(jù)建立家譜void DestroyFamilytree();/刪除家譜int SaveFamilytree(CString filename);/保存家譜void PreOrderTraverse(FILE* fp,Person& T ,void (*Visit)(FILE* fp,Person& T);/先序遍歷(為保存家譜而做)void PostOrderTraverse(Person& T,void (*Visit)(Person& T);/后序遍歷(為刪除家譜而做)void Find(Person& T,Person& Tname,ch
43、ar* name);從根結(jié)點(diǎn)出發(fā),搜索 name所在結(jié)點(diǎn),如找到,存于Tname中,找不到,Tname為0/使用前確保Tname指針為0void Find(Person&T,Person*& Tname,int month,int day);從根結(jié)點(diǎn)出發(fā),搜索家譜中birthday.month 等于month,birthday.day 等于day的所有結(jié)點(diǎn),如找到,存于以Tname為首地址的指針數(shù)組中,找不到,Tname為0使用前確保Tname/指針為0void Add(Person parent,Person addNode);/把a(bǔ)ddnode加為結(jié)點(diǎn)parent 的孩子v
44、oid Delete(Person& rootNode);/刪除以rootNode為根結(jié)點(diǎn)的所有結(jié)點(diǎn)void Modify(Person& pNode,Person newValue);修改pNode結(jié)點(diǎn)為新值newValuevoid SortByBirthday(QuickSortNode* order);/對(duì)家譜以出生日期排序,并把排序結(jié)果放在數(shù)組order中void GetPersonNums(Person&T,int& personNums);/得到家譜中總?cè)藬?shù)int InGenerationPos(Person pNode);/返回pNode在家譜中是
45、第幾代int InSiblingPos(Person pNode);返回pNode在其兄弟中的排行int ChildNums(Person pNode);/返回pNode孩子數(shù)int CompareDate(Date date1,Date date2);/比較兩日期的大小bool IsDateValid(Date date);/檢驗(yàn)日期是否合法Person& GetRoot();/得到根結(jié)點(diǎn)friend void SaveNode(FILE* fp,Person& pNode);/保存結(jié)點(diǎn)pNode到文件fp中friend void DestroyNode(Person&
46、; pNode);/刪除結(jié)點(diǎn)private:Person T;/二叉樹的根結(jié)點(diǎn)int ReadNode(FILE* fp,Person&T,char* parentname);從文件fp中讀取信息到結(jié)點(diǎn)T中,讀取此結(jié)點(diǎn)的父親姓名到parentnaem中(供CreateFamilytree函數(shù)調(diào)用)void InsertSibling(Person& firstSibling,Person insertSibling);/把insertSibling 插入到以firstSibling為首的兄弟中(供CreateFamilytree 函數(shù)調(diào)用)void CopyInfoFromBi
47、TreeToArray(Person&T,QuickSortNode*&order);把家譜中以pNode結(jié)點(diǎn)為根結(jié)點(diǎn)的出生日期拷貝到快速排序結(jié)構(gòu)數(shù)組order中(供SortByBirthday 函數(shù)調(diào)用)void QuickSort(QuickSortNode* order,int low,int high);/Korderlowhigh中的記錄進(jìn)行快速排序(供SortByBirthday 函數(shù)調(diào)用)int Partition(QuickSortNode* order,int low,int high);/Korderlow.high中的記錄進(jìn)行一次排序 (供QuickSor
48、t 函數(shù)調(diào)用)bool IsLeapYear(int year);判斷是否閏年(供IsDateValid調(diào)用,以檢查日期是否合法)根據(jù)MFC的特點(diǎn),采用CfamilytreeDlg類實(shí)現(xiàn)用戶窗口界面指令對(duì)于家譜的各種操作。class CFamilytreeDlg : public CDialogpublic:void SaveTip();/保存提示void InitListCtrl();/初始化列表控件void RefreshTree();/刷新樹,(即刷新顯示)void RefreshList();/刷新列表void DisplayFamilytree(Person& pNode);
49、/顯示樹void DisplayInListCtrl(Person pNode);/把pNode結(jié)點(diǎn)的信息在列表控件中顯示出來void Display(CString temp);/在列表控件中顯示其他信息void FindInTree(HTREEITEM& hRootItem,HTREEITEM& hItem,char* name);/在樹hRootItem 中查找name所在結(jié)點(diǎn),如找到,把其結(jié)點(diǎn)句柄存入hItem中,找不到,/hItem為0.注意,使用該函數(shù)時(shí),確保 hItem 初值為0void BirthdayTip();/每次打開一新家譜文件時(shí)的生日提示void DisplayGenerationInfo(Person& pNode,bool& flag,int count,int generation);/顯示所有第generation代人的信息void AddToTree(HTREEITEM hParentItem,Person addnode );/把a(bǔ)ddnode加入到樹的hParentItem結(jié)點(diǎn)中去private:char savepathMAX_CHARNUM;/家譜第一次被保存時(shí)的路徑bool IsFamilytreeModified;/家譜是否被修改標(biāo)
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度專業(yè)演出場(chǎng)地租賃及活動(dòng)策劃服務(wù)協(xié)議3篇
- 2025年度碼頭貨物短途運(yùn)輸及環(huán)保處理服務(wù)合同4篇
- 2024-2025學(xué)年高中歷史第五單元近現(xiàn)代中國的先進(jìn)思想第20課西學(xué)東漸課后習(xí)題含解析岳麓版必修3
- 二零二五版生態(tài)修復(fù)工程承攬合同模板-施工與生態(tài)保護(hù)2篇
- 2025年度門衛(wèi)人員安全教育與聘用合同
- 2024版派遣員工合同樣本2篇
- 2025版高端商務(wù)辦公空間租賃合同4篇
- 2024碼頭場(chǎng)地租賃合同
- 2024版天然氣安全運(yùn)輸合同
- 2024鐵路旅客運(yùn)輸服務(wù)質(zhì)量監(jiān)督合同3篇
- 機(jī)械點(diǎn)檢員職業(yè)技能知識(shí)考試題庫與答案(900題)
- 成熙高級(jí)英語聽力腳本
- 北京語言大學(xué)保衛(wèi)處管理崗位工作人員招考聘用【共500題附答案解析】模擬試卷
- 肺癌的診治指南課件
- 人教版七年級(jí)下冊(cè)數(shù)學(xué)全冊(cè)完整版課件
- 商場(chǎng)裝修改造施工組織設(shè)計(jì)
- (中職)Dreamweaver-CC網(wǎng)頁設(shè)計(jì)與制作(3版)電子課件(完整版)
- 統(tǒng)編版一年級(jí)語文上冊(cè) 第5單元教材解讀 PPT
- 中班科學(xué)《會(huì)說話的顏色》活動(dòng)設(shè)計(jì)
- 加減乘除混合運(yùn)算600題直接打印
- ASCO7000系列GROUP5控制盤使用手冊(cè)
評(píng)論
0/150
提交評(píng)論