家譜管理系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)_第1頁(yè)
家譜管理系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)_第2頁(yè)
家譜管理系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)_第3頁(yè)
家譜管理系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)_第4頁(yè)
家譜管理系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)_第5頁(yè)
已閱讀5頁(yè),還剩16頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、實(shí)用標(biāo)準(zhǔn)文案課程設(shè)計(jì)報(bào)告課程名稱(chēng) 數(shù)據(jù)結(jié)構(gòu) 課題名稱(chēng) 排序綜合 專(zhuān)業(yè) 班級(jí) 學(xué)號(hào)姓名 聯(lián)系方式 指導(dǎo)教師20 11 年 12 月 21 日目 錄1. 問(wèn)題陳述32設(shè)計(jì)方法闡述32.1總體規(guī)劃3 2.2功能構(gòu)想42.2.1增加成員42.2.2修改成員資料52.2.3刪除成員62.2.4打開(kāi)家譜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板塊整合15 2.4調(diào)試分析193總結(jié)194. 測(cè)試結(jié)果201問(wèn)題陳述家譜用于記錄某家族歷代家族成員的情況與關(guān)系?,F(xiàn)編制一個(gè)家

2、譜資料管理軟件,實(shí)現(xiàn)對(duì)一個(gè)家族所有的資料進(jìn)行收集整理。支持對(duì)家譜的存儲(chǔ)、更新、查詢(xún)、統(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ù)類(lèi)型等等,只有確定了數(shù)據(jù)類(lèi)型和數(shù)據(jù)結(jié)構(gòu),才能在此基礎(chǔ)上進(jìn)行各種算法的設(shè)計(jì)和程序的編寫(xiě)。首先是考慮數(shù)據(jù)類(lèi)型。在家譜中,家族成員是最基本的組成部分,對(duì)于家族管理中,已經(jīng)不能再進(jìn)行細(xì)分了,所以選定家族成員作為數(shù)據(jù)的基本類(lèi)型,并在程序中定義COperationFamilytree 類(lèi)。其中COperationFamilytree 類(lèi)的各種屬性可以根據(jù)需要進(jìn)行添加或刪除

3、,從日常生活應(yīng)用的角度出發(fā),制定了COperationFamilytree 類(lèi)中包含了一下屬性:char nameMAX_CHARNUM; /姓名Date birthday; /出生日期In tsex; /性別char addrMAX_CHARNUM; /基本資料int live; /健在否Date deathday; /死亡日期int ChildNums(Person pNode) ; /返回pNode孩子數(shù)intInSiblingPos(Person pNode); /返回pNode在其兄弟中的排行為方便計(jì)算機(jī)進(jìn)行比較,在familytree類(lèi)的某些屬性中用數(shù)字代替了某些不會(huì)改變的字符串,

4、譬如性別(1代表男,0代表女)、判斷是否健在(1為是,0為否)。在設(shè)置日期上,為方便以后的計(jì)算與比較,也將日期用整型數(shù)字表示19990505表示1999年5月5日,這種表示方法只需在輸入和輸出上作少許的運(yùn)算便可方便地與日期進(jìn)行轉(zhuǎn)換。在家族關(guān)系的表示上,并沒(méi)有用相關(guān)家屬的姓名作為儲(chǔ)存數(shù)據(jù),而僅僅是存儲(chǔ)了各關(guān)系親屬的ID,方便日后作為指針指示調(diào)用相對(duì)應(yīng)的家族成員。其中在屬性pNode上,其表示的是下一個(gè)同父母的弟或妹ID,也就是說(shuō),當(dāng)某家族成員有若干個(gè)子女,其pNode僅指向第一個(gè)孩子,其余的孩子如何表示呢?可以通過(guò)第一個(gè)孩子的pNode指示,如此類(lèi)推,直到孩子的pNode =0為止。這樣就可以避

5、免需在程序設(shè)計(jì)時(shí)預(yù)定父母可以擁有的孩子數(shù),有多少孩子就表示多少,實(shí)現(xiàn)了動(dòng)態(tài)的儲(chǔ)存數(shù)據(jù)。在選擇數(shù)據(jù)結(jié)構(gòu)方面,從直觀來(lái)說(shuō),選擇樹(shù)型結(jié)構(gòu)通過(guò)鏈表來(lái)連接數(shù)據(jù)無(wú)疑是最直觀易懂的,我在一開(kāi)始構(gòu)思的時(shí)候也是從樹(shù)型結(jié)構(gòu)去想的,但當(dāng)構(gòu)思到如何存儲(chǔ)和提取數(shù)據(jù)是,便發(fā)現(xiàn)了問(wèn)題。毫無(wú)疑問(wèn),用指針來(lái)處理數(shù)據(jù)的確是方便直觀,但當(dāng)我要儲(chǔ)存數(shù)據(jù)是,便發(fā)現(xiàn)把指針儲(chǔ)存進(jìn)去是沒(méi)有作用的,因?yàn)楫?dāng)我們下一次讀取數(shù)據(jù)的時(shí)候,數(shù)據(jù)內(nèi)存地址已經(jīng)不同了,不在是我們上次存儲(chǔ)數(shù)據(jù)時(shí)的地址,也就是說(shuō)指針這時(shí)已經(jīng)是沒(méi)有作用了。要解決這樣的問(wèn)題,我們必須要在存儲(chǔ)數(shù)據(jù)之前,先家族樹(shù)序列化,用數(shù)組(或者其他可以用數(shù)字表示關(guān)系的方法)來(lái)存儲(chǔ),并且,再下一次讀

6、取數(shù)據(jù)時(shí),再把數(shù)據(jù)按照序列號(hào)重新組成一個(gè)家族樹(shù),過(guò)程比較繁復(fù),而且實(shí)現(xiàn)起來(lái)也不容易。所以我便考慮直接用數(shù)組來(lái)存儲(chǔ)數(shù)據(jù),即使是在內(nèi)存中也用數(shù)組來(lái)處理數(shù)據(jù)間的聯(lián)系。運(yùn)用順序表這個(gè)結(jié)構(gòu)雖然不是那么直觀,但在查找數(shù)據(jù)時(shí)的算法設(shè)計(jì)比較簡(jiǎn)單容易實(shí)現(xiàn),效率高,而且在內(nèi)存中的數(shù)據(jù)可以直接讀入到文件中,文件中的數(shù)據(jù)也可以直接讀入內(nèi)存,不需要進(jìn)行轉(zhuǎn)換。所以在衡量的各個(gè)方面之后,我決定用數(shù)組來(lái)處理數(shù)據(jù)間的聯(lián)系。2.2功能構(gòu)想構(gòu)想好總體規(guī)劃之后,便開(kāi)始設(shè)計(jì)程序中需要用到的各個(gè)功能函數(shù),初步構(gòu)想是要先實(shí)現(xiàn)最基本的幾項(xiàng)功能,其中數(shù)據(jù)操作的有:增加成員,修改成員資料,刪除成員;數(shù)據(jù)存取的有:打開(kāi)家譜,新建家譜,保存家譜,另

7、存家譜;數(shù)據(jù)查詢(xún)的有:查看某代信息,按姓名查找,按生日查找,查看成員關(guān)系,按出生日期排序等等。2.2.1增加成員這項(xiàng)功能做得不夠理想,在規(guī)劃時(shí)沒(méi)有把成員以配偶的形式增加,而只能以子女的形式增加。對(duì)應(yīng)的函數(shù)代碼如下:void COperationFamilytree:Add(Person parent, Person addNode)/本函數(shù)把a(bǔ)ddNode結(jié)點(diǎn)加入到其父結(jié)點(diǎn)parent下addNode->child=addNode->sibling=0;/把欲加入的結(jié)點(diǎn)所有指針域置空addNode->parent=parent;/因addNode欲加為parent的孩子,故a

8、ddNode結(jié)點(diǎn)的父指針域應(yīng)指向parentif(parent=0)/若parent為0,則表示欲加addNode為根結(jié)點(diǎn)if(T=0)/若本為空家譜T=addNode;/把a(bǔ)ddNode當(dāng)成根結(jié)點(diǎn)return;addNode->child=T;/使原來(lái)的根結(jié)點(diǎn)成為新根結(jié)點(diǎn)的孩子T->parent=addNode;T=addNode;return;if(parent->child=0)/parent無(wú)孩子,把a(bǔ)ddNode加入其孩子parent->child=addNode;elseInsertSibling(parent->child,addNode);/把a(bǔ)d

9、dNode加到parent孩子的兄弟域中2.2.2修改成員資料修改成員這項(xiàng)功能實(shí)現(xiàn)起來(lái)比較簡(jiǎn)單,找到要修改成員的名字,再輸入新修改的值,整個(gè)函數(shù)沒(méi)有什么需要運(yùn)用算法的地方,但如果想真正寫(xiě)好這個(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)return;CModifyInfoDlg dlg;HTREEITEM hItem;hItem=m_

10、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);Person newValue=new PersonNode; strcpy(newValue-&

11、gt;,dlg.m_newname);/判斷家譜中是否已有用戶(hù)給定的新名字if(strcmp(newValue->,oldname)=0) ;/用戶(hù)不修改姓名elsePerson p=0;operFamilytree.Find(operFamilytree.GetRoot(),p,newValue->);/查找家譜中有沒(méi)有此人if(p!=0)AfxMessageBox("家譜中已有此人!");delete newValue;return;strcpy(newValue->info.addr,dlg.m_

12、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->info.live)/如若過(guò)世,則應(yīng)有死亡日期newValue->info.deathda

13、y.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;return;if(operFamilytree.CompareDate(newValue->inf

14、o.deathday,newValue->info.birthday)=-1)AfxMessageBox("此人死亡日期不可能比其出生日期早!");return;operFamilytree.Modify(oneself,newValue);RefreshTree();RefreshList();IsFamilytreeModified=true;/置家譜修改標(biāo)記為真delete newValue;2.2.3刪除成員用數(shù)組來(lái)儲(chǔ)存數(shù)據(jù),最麻煩的就是刪除數(shù)組元素了,在這個(gè)程序中,刪除數(shù)組不但意味著要重新排列各成員,還要重新更新各成員的關(guān)系,所以我個(gè)人認(rèn)為在這個(gè)程序中,刪除

15、成員函數(shù)可以說(shuō)是一個(gè)難點(diǎn)。通過(guò)分析,發(fā)現(xiàn)刪除成員的情況就只有兩種,只要針對(duì)這兩種情況處理好刪除,就可以完成成員刪除這個(gè)功能。,刪除的成員是出于家族中最底層的,也就是刪除該成員不會(huì)牽連其他成員,但這也需要處理好其父母的孩子數(shù)。,刪除的成員還有子孫,則需要連帶所有子孫都要?jiǎng)h除出家譜。遇到這種情況,不但要像上一種情況那樣處理父母和兄弟姐妹的關(guān)系,還要記錄牽連刪除的總?cè)藬?shù),因?yàn)閯h除不再是簡(jiǎn)單刪除了一個(gè)人,而是若干個(gè),通過(guò)遞歸調(diào)用,可以統(tǒng)計(jì)出需要?jiǎng)h除的數(shù)目 刪除函數(shù)的相關(guān)代碼如下:void COperationFamilytree:Delete(Person &rootNode)/本函數(shù)刪除以r

16、ootNode為根結(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è)孩子Person p=rootNode->parent->child;/找到rootNode應(yīng)在兄弟中的位置for(;p

17、->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);elseDestroyNode(rootNode);2.2.4打開(kāi)家譜打開(kāi)家譜函數(shù)的相關(guān)代碼如下:int COperationFamilytre

18、e:ReadNode(FILE *fp, Person &T,char* parentname)/本函數(shù)從文件fp中讀取信息到結(jié)點(diǎn)T中,并讀取結(jié)點(diǎn)的父親名字到字符數(shù)組parentname中/分別讀取結(jié)點(diǎn)值,為:姓名,出生日期(年,月,日),婚否,地址,健在否,(如過(guò)世,還有死亡日期)fscanf(fp,"%s%d%d%d%d%s%d",T->,&T->info.birthday.year,&T->info.birthday.month,&T->info.birthday.day,&T->

19、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",parentname);if(!IsDateValid(T->info.birthday)/出生日期合法性檢查returnFILE_DATA_NOT_PRACTIC

20、AL;if(T->info.live=0)/若過(guò)世,死亡日期合法性檢查if (CompareDate(T->info.birthday,T->info.deathday)!=-1)return FILE_DATA_NOT_PRACTICAL;if(!IsDateValid(T->info.deathday)returnFILE_DATA_NOT_PRACTICAL;return OK;2.2.5新建家譜新建家譜函數(shù)的相關(guān)代碼如下:void COperationFamilytree:NewFamilytree()/本函數(shù)新建一空家譜DestroyFamilytree();

21、/刪除原有家譜T=0;int COperationFamilytree:CreateFamilytree(CString filename)/本函數(shù)建立一新家譜DestroyFamilytree();/建立一新家譜之前,清空原有家譜FILE* fp;if(fp=fopen(filename,"r")=0)/打開(kāi)文件filenamereturn READ_FILE_ERROR;T=new PersonNode;/定義根結(jié)點(diǎn)if(!T)return NOT_ENOUGH_MEMORY;T->child=0;T->sibling=0;T->parent=0;Pe

22、rson parentT, temp;/定義兩個(gè)臨時(shí)結(jié)點(diǎn)char parentnameMAX_CHARNUM;/定義一個(gè)臨時(shí)字符串?dāng)?shù)組/讀取根結(jié)點(diǎn)值,(姓名,出生日期(年,月,日),婚否,地址,健在否,(如過(guò)世,還有死亡日期)int result;result=ReadNode(fp,T,parentname);if(result=FILE_DATA_NOT_PRACTICAL)delete T;/若不合法,刪除申請(qǐng)的堆空間T=0;return result;if(strcmp(T->,parentname)=0)/根結(jié)點(diǎn)名字與其父親名字相同,說(shuō)明為空樹(shù)delete T

23、;T=0;return PEDIGREE_EMPTY;temp=new PersonNode;/申請(qǐng)一結(jié)點(diǎn)if(!temp)/申請(qǐng)失敗DestroyFamilytree();/釋放申請(qǐng)空間return NOT_ENOUGH_MEMORY;result=ReadNode(fp,temp,parentname);while(strcmp(temp->,parentname)&&strcmp(temp->,"end")/讀取信息結(jié)束的條件是兩個(gè)人的名字同為endif(result=FILE_DATA_NOT_PRAC

24、TICAL)/若數(shù)據(jù)不合法,釋放已申請(qǐng)空間,然后返回delete temp;DestroyFamilytree();return result;parentT=0; Find(T,parentT,parentname);/找到parentname所在結(jié)點(diǎn)parentTif(parentT)/如果parentT存在,說(shuō)明parentname在家譜中/并且parentname為temp的父親int cmp;cmp=CompareDate(temp->info.birthday,parentT->info.birthday);if(cmp<0)/若孩子出生日期比父親大,則不對(duì)del

25、ete temp;DestroyFamilytree();returnFILE_DATA_NOT_PRACTICAL;temp->child=temp->sibling=0;temp->parent=parentT;/temp的父指針指向parentT;if(parentT->child)/parentname已經(jīng)有孩子InsertSibling(parentT->child,temp);/ifelse/parentname無(wú)孩子,則temp應(yīng)為parentT->child=temp;/parentname的第一個(gè)孩子/ifelse/parentT不存在,說(shuō)

26、明家譜中不存在parentname此人DestroyFamilytree();/返回出錯(cuò)信息return FILE_DATA_ERROR;temp=new PersonNode;/申請(qǐng)一結(jié)點(diǎn)if(!temp)/申請(qǐng)失敗DestroyFamilytree();/釋放申請(qǐng)空間return NOT_ENOUGH_MEMORY;result=ReadNode(fp,temp,parentname);/繼續(xù)讀取數(shù)據(jù)/whileif(temp)delete temp;fclose(fp);return OK;2.2.6保存家譜保存家譜函數(shù)的相關(guān)代碼如下:int COperationFamilytree:S

27、aveFamilytree(CString filename)/本函數(shù)保存家譜到文件filename中FILE* fp;if(fp=fopen(filename,"w")=0)/打開(kāi)文件filenamereturn WRITE_FILE_ERROR;PreOrderTraverse(fp,T,SaveNode);/從根結(jié)點(diǎn)開(kāi)始存儲(chǔ)家譜數(shù)據(jù)/置家譜數(shù)據(jù)結(jié)束標(biāo)記(一結(jié)點(diǎn)的名字與其父結(jié)點(diǎn)的名字同為end)fprintf(fp,"%s %d %d %d %d %s %d %s","end",1999,12,2,1,"end"

28、;,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,Visit);PreOrderTraverse(fp,T->sibling,Visit);void SaveNode(FILE *fp

29、, Person &pNode)/本函數(shù)向文件fp中存取一結(jié)點(diǎn)pNodechar 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.marry,pNode->info.addr,pNode->info.live);if(pNode->info.

30、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->);elsefprintf(fp," %s","-1");fprintf(fp," %c",ch);2.2.7查看某代信息查看

31、某代信息函數(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;2.2.8按姓名查找按姓名查找函數(shù)的相關(guān)代碼如下:void COperationFamilytree:Find(Person& T,Person& Tname,char* name)/本函數(shù)以T為根結(jié)點(diǎn)開(kāi)始,搜索結(jié)點(diǎn)信息中名字等于name的結(jié)點(diǎn)if(T)/

32、如果T存在if(strcmp(T->,name)=0)/T結(jié)點(diǎn)姓名和name相同,把T結(jié)點(diǎn)指針傳給TnameTname=T;elseFind(T->sibling,Tname,name);/對(duì)T的兄弟遞歸搜索Find(T->child,Tname,name);/對(duì)T的孩子遞歸搜索2.2.9按生日查找按生日查找函數(shù)的相關(guān)代碼如下:void COperationFamilytree:Find(Person &T, Person*& Tname,int month, int day)/本函數(shù)以T為根結(jié)點(diǎn)開(kāi)始,搜索結(jié)點(diǎn)信息中生日等于month,day

33、的結(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=month&&temp->info.birthday.day=day)*Tname=temp;Tname+;temp=N

34、ULL;Find(T->child,Tname,month,day);/對(duì)T的孩子遞歸搜索Find(T->sibling,Tname,month,day);/對(duì)T的兄弟遞歸搜索2.2.10查看成員關(guān)系查看成員關(guān)系函數(shù)的相關(guān)代碼如下:void CFamilytreeDlg:OnFamilytreeRelations() / TODO: Add your command handler code hereCRelationsDlg dlg;if(dlg.DoModal()=IDCANCEL)return;UpdateData(FALSE);int pos1,pos2;Person on

35、eself=0;char name1MAX_CHARNUM,name2MAX_CHARNUM;strcpy(name1,dlg.m_firstname);operFamilytree.Find(operFamilytree.GetRoot(),oneself,name1);if(oneself)pos1=operFamilytree.InGenerationPos(oneself);elseAfxMessageBox("本家譜中找不到"+CString(name1)+"!");return;Person p,q;CString generation;ge

36、neration+=oneself->;generation+="在家譜中的位置: "for(q=oneself,p=q->parent;p!=0;p=p->parent)generation+=q->;generation+= "->"q=p;generation+=q->;generation+="n" oneself=0;strcpy(name2,dlg.m_secondname);operFamilytree.Find(operFamil

37、ytree.GetRoot(),oneself,name2);if(oneself)pos2=operFamilytree.InGenerationPos(oneself);elseAfxMessageBox("本家譜中找不到"+CString(name2)+"!");return;generation+=oneself->;generation+="在家譜中的位置: "for(q=oneself,p=q->parent;p!=0;p=p->parent)generation+=q->info

38、.name;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 if(pos1<pos2)cmpResult.Format("%s在第%d代,%s在第%d代,%s是%s的長(zhǎng)輩.",name

39、1,pos1,name2,pos2,name1,name2);elsecmpResult.Format("%s與%s同在第%d代.",name1,name2,pos2);generation+=cmpResult;AfxMessageBox(generation);2.2.11按出生日期排序按出生日期排序函數(shù)的相關(guān)代碼如下:void COperationFamilytree:SortByBirthday(QuickSortNode *order)/本函數(shù)對(duì)順序表order以出生日期的大小排序int totalNums=0;QuickSortNode* startaddr=o

40、rder;startaddr+;GetPersonNums(T,totalNums);CopyInfoFromBiTreeToArray(T,startaddr);QuickSort(order,1,totalNums);2.3板塊整合以上的功能設(shè)計(jì)生成的各種函數(shù)文件僅是獨(dú)立的各個(gè)板塊,要將這些函數(shù)有機(jī)地聯(lián)系起來(lái),才能形成可以應(yīng)用的程序,首先我用了一個(gè)DefineStruct.h聲明數(shù)據(jù)類(lèi)型與各個(gè)應(yīng)用函數(shù),其代碼如下:根據(jù)家譜的特點(diǎn),采用孩子-兄弟的二叉樹(shù)鏈表表示法(鏈表的基本單位為以結(jié)構(gòu) PersomNode表示的結(jié)點(diǎn)),各種操作以COperationFamilytree 類(lèi)來(lái)實(shí)現(xiàn)。以下是C

41、operationFamilytree 類(lèi)包含的數(shù)據(jù)成員及基本操作class COperationFamilytree /定義家族成員結(jié)構(gòu)public:COperationFamilytree();/構(gòu)造函數(shù)virtual COperationFamilytree();/析構(gòu)函數(shù)void NewFamilytree();/新建一空家譜int CreateFamilytree(CString filename);/從輸入文件filename 中讀取數(shù)據(jù)建立家譜void DestroyFamilytree();/刪除家譜int SaveFamilytree(CString filename);/保

42、存家譜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,char* name);/從根結(jié)點(diǎn)出發(fā),搜索name 所在結(jié)點(diǎn),如找到,存于Tname 中,找不到,Tname 為0/使用前確保Tname 指針為0voi

43、d 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 的孩子void Delete(Person& rootNode);/刪除以rootNode 為根結(jié)點(diǎn)的所有結(jié)點(diǎn)void Mod

44、ify(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 在家譜中是第幾代int InSiblingPos(Person pNode);/返回pNode 在其兄弟中的排行int Chi

45、ldNums(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& pNode);/刪除結(jié)點(diǎn)private:Person T;/二叉樹(shù)的根結(jié)點(diǎn)int ReadNode(F

46、ILE* 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 CopyInfoFromBiTreeToArray(Person&T,QuickSortNode*&ord

47、er);/把家譜中以pNode 結(jié)點(diǎn)為根結(jié)點(diǎn)的出生日期拷貝到快速排序結(jié)構(gòu)數(shù)組order 中(供SortByBirthday 函數(shù)調(diào)用)void QuickSort(QuickSortNode* order,int low,int high);/對(duì)orderlow.high中的記錄進(jìn)行快速排序(供SortByBirthday 函數(shù)調(diào)用)int Partition(QuickSortNode* order,int low,int high);/對(duì)orderlow.high中的記錄進(jìn)行一次排序(供QuickSort 函數(shù)調(diào)用)bool IsLeapYear(int year);/判斷是否閏年(供Is

48、DateValid 調(diào)用,以檢查日期是否合法)根據(jù)MFC 的特點(diǎn),采用CfamilytreeDlg 類(lèi)實(shí)現(xiàn)用戶(hù)窗口界面指令對(duì)于家譜的各種操作。class CFamilytreeDlg : public CDialogpublic:void SaveTip();/保存提示void InitListCtrl();/初始化列表控件void RefreshTree();/刷新樹(shù),(即刷新顯示)void RefreshList();/刷新列表void DisplayFamilytree(Person& pNode);/顯示樹(shù)void DisplayInListCtrl(Person pNode)

49、;/把pNode 結(jié)點(diǎn)的信息在列表控件中顯示出來(lái)void Display(CString temp);/在列表控件中顯示其他信息void FindInTree(HTREEITEM& hRootItem,HTREEITEM& hItem,char* name);/在樹(shù)hRootItem 中查找name 所在結(jié)點(diǎn),如找到,把其結(jié)點(diǎn)句柄存入hItem 中,找不到,/hItem 為0.注意,使用該函數(shù)時(shí),確保hItem 初值為0void BirthdayTip();/每次打開(kāi)一新家譜文件時(shí)的生日提示void DisplayGenerationInfo(Person& pNode,bool& flag,int count,int generation);/顯示所有第generation 代人的信息void AddToTree(HTREEITEM hParentItem,Person addnode );/把a(bǔ)ddnode 加入到樹(shù)的hParentItem 結(jié)點(diǎn)中去private:char savepathMAX_CHARNUM;/家譜第一次被保存時(shí)的路徑bool IsFamilytreeMod

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論