版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)(家族關(guān)系查詢(xún)系統(tǒng))數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)(家族關(guān)系查詢(xún)系統(tǒng))數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)(家族關(guān)系查詢(xún)系統(tǒng))數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)(家族關(guān)系查詢(xún)系統(tǒng))編制僅供參考審核批準(zhǔn)生效日期地址:電話(huà):傳真:郵編:1課程設(shè)計(jì)介紹課程設(shè)計(jì)項(xiàng)目簡(jiǎn)介家譜是一種以表譜形式,記載一個(gè)以血緣關(guān)系為主體的家族世系繁衍和重要人物事跡的特殊圖書(shū)載體。家譜是中國(guó)特有的文化遺產(chǎn),是中華民族的三大文獻(xiàn)之一,屬珍貴的人文資料,對(duì)于歷史學(xué),民俗學(xué),人口學(xué),社會(huì)學(xué)和經(jīng)濟(jì)學(xué)的深入研究,均有不可替代的重要功能。本項(xiàng)目對(duì)家譜管理進(jìn)行簡(jiǎn)單的模擬,以實(shí)現(xiàn)查看祖先和子孫個(gè)人信息、插入家族成員等功能。課設(shè)題目分析本程序的實(shí)質(zhì)是完成對(duì)家譜成員信息的建立、查找、插入等功能??梢允紫榷x家族成員的數(shù)據(jù)結(jié)構(gòu),然后將每個(gè)功能寫(xiě)成一個(gè)函數(shù)來(lái)完成對(duì)數(shù)據(jù)的操作,最后完成主函數(shù)以驗(yàn)證各個(gè)函數(shù)功能并得出運(yùn)行結(jié)果。本程序包含以下幾個(gè)模塊建立家族關(guān)系樹(shù)。此模塊將構(gòu)建一個(gè)家族關(guān)系,對(duì)數(shù)據(jù)初始化,構(gòu)造關(guān)系樹(shù)并錄入數(shù)據(jù)一遍后續(xù)程序使用。添加新成員。此模塊將添加一個(gè)新成員,實(shí)現(xiàn)對(duì)家族關(guān)系的修改。家族關(guān)系的查詢(xún)。此模塊將實(shí)現(xiàn)對(duì)家族不同關(guān)系的查詢(xún)主程序模塊。此模塊實(shí)現(xiàn)整個(gè)程序的進(jìn)入和進(jìn)出,以及各種初始化處理。課程題目原理與數(shù)據(jù)結(jié)構(gòu)因?yàn)榧易宓某蓡T之間存在一個(gè)對(duì)多個(gè)的層次結(jié)構(gòu)關(guān)系,所以不能用線性表來(lái)表示和實(shí)現(xiàn)。家譜從形狀上看像一顆倒長(zhǎng)的樹(shù),所以用樹(shù)結(jié)構(gòu)來(lái)表示比較合適。樹(shù)形結(jié)構(gòu)是一類(lèi)非常重要的非線性數(shù)據(jù)結(jié)構(gòu),直觀看來(lái)樹(shù)是以分支關(guān)系定義的層次結(jié)構(gòu)。因此本課程設(shè)計(jì)可以采用的數(shù)據(jù)結(jié)構(gòu)有樹(shù)狀結(jié)構(gòu)和隊(duì)列。樹(shù)狀結(jié)構(gòu)采用三叉鏈表來(lái)實(shí)現(xiàn),隊(duì)列采用鏈?zhǔn)疥?duì)列實(shí)現(xiàn)。功能分析說(shuō)明圖家族關(guān)系查詢(xún)系統(tǒng)家族關(guān)系查詢(xún)系統(tǒng)退出系統(tǒng)退出系統(tǒng)打開(kāi)一個(gè)家族關(guān)系按關(guān)系查找各個(gè)家庭成員建立一個(gè)家族關(guān)系添加一個(gè)家庭成員打開(kāi)一個(gè)家族關(guān)系按關(guān)系查找各個(gè)家庭成員建立一個(gè)家族關(guān)系添加一個(gè)家庭成員查找一個(gè)成員的兄弟查找一個(gè)成員的祖先查找成員的子孫后代查找一個(gè)成員的孩子查找成員的堂兄弟查找成員祖先路徑查找成員是第幾代查找一個(gè)成員雙親查找一個(gè)成員的兄弟查找一個(gè)成員的祖先查找成員的子孫后代查找一個(gè)成員的孩子查找成員的堂兄弟查找成員祖先路徑查找成員是第幾代查找一個(gè)成員雙親2分析與實(shí)現(xiàn)基本數(shù)據(jù)結(jié)構(gòu)和棧隊(duì)的操作結(jié)點(diǎn)基本數(shù)據(jù)結(jié)構(gòu)和鏈隊(duì)的定義/*家族關(guān)系樹(shù)實(shí)現(xiàn)*/#include<>#include<>#include<>#include<>#include<>#include<>#include<>#include<>#defineTRUE1#defineFALSE0#defineOK1#defineERROR-1#defineINFEASIBLE-1typedefcharDataType;#defineMAXNUM20typedefstructTriTNode/*樹(shù)的三叉鏈表存儲(chǔ)結(jié)構(gòu)*/{ DataTypedata[MAXNUM]; structTriTNode*parent;/*雙親*/ structTriTNode*lchild;/*左孩子*/ structTriTNode*rchild;/*右孩子*/}TriTree;typedefstructNode/*隊(duì)列的結(jié)點(diǎn)結(jié)構(gòu)*/{ TriTree*info;structNode*next;}Node;typedefstruct/*鏈接隊(duì)列類(lèi)型定義*/{ structNode*front; /*頭指針*/structNode*rear; /*尾指針*/}LinkQueue;DataTypefname[MAXNUM],family[50][MAXNUM];/*全局變量*/鏈隊(duì)的基本操作LinkQueue*LQueueCreateEmpty()/*建立一個(gè)空隊(duì)列*/{ LinkQueue*plqu=(LinkQueue*)malloc(sizeof(LinkQueue));if(plqu!=NULL)plqu->front=plqu->rear=NULL;else { printf("內(nèi)存不足!\n"); returnNULL; } returnplqu;}intLQueueIsEmpty(LinkQueue*plqu)/*判斷鏈接表示隊(duì)列是否為空隊(duì)列*/{return(plqu->front==NULL);}voidLQueueEnQueue(LinkQueue*plqu,TriTree*x)/*進(jìn)隊(duì)列*/{Node*p=(Node*)malloc(sizeof(Node));if(p==NULL)printf("內(nèi)存分配失敗!\n");else {p->info=x;p->next=NULL;if(plqu->front==NULL)/*原來(lái)為空隊(duì)*/plqu->front=p;elseplqu->rear->next=p;plqu->rear=p;}}intLQueueDeQueue(LinkQueue*plqu,TriTree*x)/*出隊(duì)列*/{Node*p;if(plqu->front==NULL) { printf("隊(duì)列空!\n"); returnERROR; }else {p=plqu->front; x=p->info;plqu->front=plqu->front->next;free(p); returnOK;}}TriTree*LQueueGetFront(LinkQueue*plqu)/*在非空隊(duì)列中求隊(duì)頭元素*/{return(plqu->front->info);}建立家族關(guān)系建立家族關(guān)系并存入文件基本思想:首先輸入家族關(guān)系的名稱(chēng),以此名稱(chēng)為文件名,建立文本文件接下來(lái)按層次輸入結(jié)點(diǎn)信息,輸入一個(gè)在文件中寫(xiě)入一行同時(shí)將輸入的信息保存到二位字符數(shù)組family中。字符數(shù)組family是全局變量,存儲(chǔ)臨時(shí)信息.注意,輸入時(shí)每個(gè)結(jié)點(diǎn)信息占一行,一個(gè)結(jié)點(diǎn)有多個(gè)兄弟,以“@”作為兄弟結(jié)束標(biāo)志,結(jié)點(diǎn)若無(wú)孩子,直接以“@”代替。依次輸入各節(jié)點(diǎn)信息,以“#”作為結(jié)束標(biāo)志。最后使用函數(shù)CreateTriTree建立家族關(guān)系樹(shù).lixianlixianliguoyuliguojunliguoqiangliyongzhiliyongruiliyongmingliwendeliwenjiaTriTree*Create(DataTypefamilyname[MAXNUM])/*建立家族關(guān)系并存入文件*/{ inti=0;/*i控制family數(shù)組下標(biāo)*/ DataTypech,str[MAXNUM];/*ch存儲(chǔ)輸入的y或n,str存儲(chǔ)輸入的字符串*/ TriTree*t; FILE*fp; strcpy(fname,familyname);/*以家族名為文本文件名存儲(chǔ)*/ strcat(fname,".txt"); fp=fopen(fname,"r");/*以讀取方式打開(kāi)文件*/ if(fp)/*文件已存在*/ { fclose(fp); printf("%s的家族關(guān)系已存在!重新建立請(qǐng)按“Y”,直接打開(kāi)請(qǐng)按“N”\n",familyname); ch=getchar(); getchar();/*接收回車(chē)*/ if(ch=='N'||ch=='n') { t=Open(familyname);/*直接打開(kāi)*/ returnt; } } if(!fp||ch=='Y'||ch=='y')/*重新建立,執(zhí)行以下操作*/ { fp=fopen(fname,"w");/*以寫(xiě)入方式打開(kāi)文件,不存在則新建*/ printf("請(qǐng)按層次輸入結(jié)點(diǎn),每個(gè)結(jié)點(diǎn)信息占一行\(zhòng)n"); printf("兄弟輸入結(jié)束以“@”為標(biāo)志,結(jié)束標(biāo)志為“#”\n."); gets(str); fputs(str,fp); fputc('\n',fp); strcpy(family[i],str);/*將成員信息存儲(chǔ)到字符數(shù)組中*/ i++;/*family數(shù)組下標(biāo)后移*/ while(str[0]!='#') { printf(".");/*以點(diǎn)提示符提示繼續(xù)輸入*/ gets(str); fputs(str,fp);/*寫(xiě)到文件中,每個(gè)信息占一行*/ fputc('\n',fp); strcpy(family[i],str);/*將成員信息存儲(chǔ)到字符數(shù)組中*/ i++;/*family數(shù)組下標(biāo)后移*/ } fclose(fp);/*關(guān)閉文件*/ t=TriTreeCreate();/*根據(jù)family數(shù)組信息創(chuàng)建三叉樹(shù)*/ printf("家族關(guān)系已成功建立!\n"); returnt;/*返回樹(shù)*/ }}建立家族關(guān)系樹(shù)基本思想:采用指針數(shù)組作為指針,保存輸入的結(jié)點(diǎn)地址。隊(duì)列的尾指針指向當(dāng)前結(jié)點(diǎn)。頭指針指向當(dāng)前結(jié)點(diǎn)的雙親結(jié)點(diǎn)。輸入的結(jié)點(diǎn)信息已存儲(chǔ)在字符數(shù)組family中。將信息復(fù)制到字符串?dāng)?shù)組“ch”中,如果"ch"不是“@”,則建立一個(gè)新結(jié)點(diǎn)。若新結(jié)點(diǎn)是第一個(gè)結(jié)點(diǎn),則它是根結(jié)點(diǎn),將其入隊(duì),指針tree指向這個(gè)根節(jié)點(diǎn);如果不是根結(jié)點(diǎn),則將當(dāng)前結(jié)點(diǎn)鏈接到雙親結(jié)點(diǎn)上,即當(dāng)前結(jié)點(diǎn)的雙親指針就是隊(duì)頭元素,然后將當(dāng)前結(jié)點(diǎn)入隊(duì)列。接著判斷flag的值,如果flag=0,表示當(dāng)前結(jié)點(diǎn)沒(méi)有左孩子,那么當(dāng)前結(jié)點(diǎn)就是雙親的左孩子。否則,當(dāng)前結(jié)點(diǎn)就是雙親的右孩子。用指針root指向剛剛?cè)腙?duì)的結(jié)點(diǎn)。繼續(xù)復(fù)制數(shù)組family的下個(gè)元素。如果“ch”是@。則flag=0(因?yàn)椤癅”后面的第一個(gè)孩子為左孩子),同時(shí)判斷“@”是否是第一次出現(xiàn),如果是第一次,則令標(biāo)志star=1;如果不是第一次出現(xiàn)。則出隊(duì)列,root指向隊(duì)頭元素(實(shí)際上root總是指向雙親結(jié)點(diǎn))。繼續(xù)復(fù)制family的下一個(gè)元素。知道遇到“#”結(jié)束。函數(shù)返回指針tree。/*建立家族關(guān)系樹(shù)*/TriTree*TriTreeCreate(){ TriTree*t,*x=NULL,*tree,*root=NULL; LinkQueue*q=LQueueCreateEmpty();/*建立一個(gè)空的隊(duì)列,存儲(chǔ)指向樹(shù)的指針*/ inti=0,flag=0,start=0; DataTypestr[MAXNUM];/*存放family數(shù)組中信息*/ strcpy(str,family[i]);/*復(fù)制*/ i++;/*family數(shù)組下標(biāo)后移*/ while(str[0]!='#')/*沒(méi)遇到結(jié)束標(biāo)志繼續(xù)循環(huán)*/ { while(str[0]!='@')/*沒(méi)遇到兄弟輸入結(jié)束標(biāo)志繼續(xù)*/ { if(root==NULL)/*空樹(shù)*/ { root=(TriTree*)malloc(sizeof(TriTree));/*申請(qǐng)空間*/ strcpy(root->data,str); root->parent=NULL; root->lchild=NULL; root->rchild=NULL; LQueueEnQueue(q,root);/*將root存入隊(duì)列*/ tree=root; } else/*不為空樹(shù)*/ { t=(TriTree*)malloc(sizeof(TriTree));/*申請(qǐng)空間*/ strcpy(t->data,str); t->lchild=NULL; t->rchild=NULL; t->parent=LQueueGetFront(q);/*當(dāng)前結(jié)點(diǎn)的雙親為隊(duì)頭元素*/ LQueueEnQueue(q,t);/*入隊(duì)*/ if(!flag)/*flag為,當(dāng)前結(jié)點(diǎn)沒(méi)有左孩子*/ root->lchild=t; else /*flag為,當(dāng)前結(jié)點(diǎn)已有左孩子*/ root->rchild=t; root=t;/*root指向新的結(jié)點(diǎn)t*/ } flag=1;/*標(biāo)記當(dāng)前結(jié)點(diǎn)已有左孩子*/ strcpy(str,family[i]); i++; } if(start!=0)/*標(biāo)記不是第一次出現(xiàn)“@”*/ { LQueueDeQueue(q,x);/*出隊(duì)*/ if(q->front!=NULL) root=LQueueGetFront(q);/*root為隊(duì)頭元素*/ } start=1;/*標(biāo)記已出現(xiàn)過(guò)“@”*/ flag=0;/*“@”后面的結(jié)點(diǎn)一定為左孩子*/ strcpy(str,family[i]); i++; } returntree;/*返回樹(shù)*/}打開(kāi)一個(gè)家族關(guān)系首先輸入家族關(guān)系名,以家族名為文件名打開(kāi)文件,如果家族關(guān)系不存在,返回空;如果存在,文件打開(kāi),讀取文件。將文件的每行信息依次存儲(chǔ)在數(shù)組family【】中。/*打開(kāi)一個(gè)家族關(guān)系*/TriTree*Open(DataTypefamilyname[MAXNUM]){ inti=0,j=0; DataTypech; FILE*fp; TriTree*t; strcpy(fname,familyname);/*以家族名為文本文件名存儲(chǔ)*/ strcat(fname,".txt"); fp=fopen(fname,"r");/*以讀取方式打開(kāi)文件*/ if(fp==NULL)/*文件不存在*/ { printf("%s的家族關(guān)系不存在!\n",familyname); returnNULL; } else { ch=fgetc(fp);/*按字符讀取文件*/ while(ch!=EOF)/*讀到文件尾結(jié)束*/ { if(ch!='\n')/*ch不為一個(gè)結(jié)點(diǎn)信息的結(jié)尾*/ { family[i][j]=ch;/*將文件信息存儲(chǔ)到family數(shù)組中*/ j++; } else { family[i][j]='\0';/*字符串結(jié)束標(biāo)志*/ i++;/*family數(shù)組行下標(biāo)后移*/ j=0;/*family數(shù)組列下標(biāo)歸零*/ } ch=fgetc(fp);/*繼續(xù)讀取文件信息*/ } fclose(fp);/*關(guān)閉文件*/ t=TriTreeCreate(family);/*調(diào)用函數(shù)建立三叉鏈表*/ printf("家族關(guān)系已成功打開(kāi)!\n"); returnt; }}在家族關(guān)系中查找一個(gè)成員是否存在用遞歸算法實(shí)現(xiàn)。如果樹(shù)空,返回NULL。如果根節(jié)點(diǎn)就是要查找的成員,返回根節(jié)點(diǎn);否則,遞歸查找它的左右子樹(shù)。/*查找一個(gè)成員是否存在*/TriTree*Search(TriTree*t,DataTypestr[]){ TriTree*temp; if(t==NULL)/*如果樹(shù)空則返回NULL*/ returnNULL; elseif(strcmp(t->data,str)==0)/*如果找到返回該成員指針*/ returnt; else/*如果沒(méi)找到遍歷左右子樹(shù)進(jìn)行查找*/ { temp=Search(t->lchild,str);/*遞歸查找*/ if(temp)/*結(jié)點(diǎn)不空則查找*/ return(Search(t->lchild,str)); else return(Search(t->rchild,str)); }}向家族中添加一個(gè)新成員基本思想:添加的新成員要根據(jù)其雙親確定其在家族中的位置。首先判斷該雙親是否在此家族關(guān)系中,若存在則查找其雙親,將新結(jié)點(diǎn)插入其雙親的最后一個(gè)孩子之后;若沒(méi)有孩子,則直接作為左孩子插入。以寫(xiě)入的方式打開(kāi)文件,如果成功打開(kāi),則更新family數(shù)組中的信息,并查找新成員的雙親所在位置和其對(duì)應(yīng)的“@”個(gè)數(shù),如果“@”個(gè)數(shù)小于雙親位置,則添加“@”實(shí)質(zhì)相等,新成員不插入到最后“@”之前。最后將family數(shù)組中信息寫(xiě)入文件保存,關(guān)閉文件。/*添加一個(gè)新成員*/voidAppend(TriTree*t){ inti=0,j,parpos=1,curpos,num,end=0,count=-1; DataTypechi[MAXNUM],par[MAXNUM];/*存儲(chǔ)輸入的孩子和其雙親結(jié)點(diǎn)*/ TriTree*tpar,*temp; FILE*fp; printf("請(qǐng)輸入要添加的成員和其父親,以回車(chē)分隔!\n."); gets(chi); printf(".");/*以點(diǎn)提示符提示繼續(xù)輸入*/ gets(par); tpar=Search(t,par);/*查找雙親結(jié)點(diǎn)是否存在*/ if(!tpar) printf("%s該成員不存在!\n"); else/*存在則添加其孩子*/ { temp=(TriTree*)malloc(sizeof(TriTree));/*申請(qǐng)空間*/ temp->parent=tpar; strcpy(temp->data,chi); temp->lchild=NULL;/*新結(jié)點(diǎn)左右孩子置空*/ temp->rchild=NULL; if(tpar->lchild) /*成員存在左孩子*/ { tpar=tpar->lchild;/*遍歷當(dāng)前成員左孩子的右子樹(shù)*/ while(tpar->rchild) /*當(dāng)前結(jié)點(diǎn)右孩子存在*/ tpar=tpar->rchild;/*繼續(xù)遍歷右孩子*/ tpar->rchild=temp;/*將新結(jié)點(diǎn)添加到所有孩子之后*/ } else/*沒(méi)有孩子則直接添加*/ tpar->lchild=temp; fp=fopen(fname,"w");/*以寫(xiě)入方式打開(kāi)文件*/ if(fp) { while(strcmp(par,family[i])!=0&&family[i][0]!='#') { if(family[i][0]!='@')/*查找雙親在數(shù)組中位置*/ parpos++;/*parpos計(jì)數(shù)*/ i++;/*family數(shù)組行下標(biāo)后移*/ } i=0;/*family數(shù)組行下標(biāo)歸*/ while(family[i][0]!='#') { if(family[i][0]=='@')/*查找“@”的個(gè)數(shù),第一個(gè)不計(jì)*/ count++;/*count累加個(gè)數(shù)*/ if(count==parpos)/*說(shuō)明此“@”與其前一個(gè)“@”之前為par的孩子*/ curpos=i;/*curpos計(jì)當(dāng)前位置*/ i++;/*family數(shù)組行下標(biāo)后移*/ } if(count<parpos)/*“@”數(shù)小于parpos數(shù)*/ { num=parpos-count;/*添加“@”個(gè)數(shù)為num*/ for(j=i;j<=i+num;j++)/*從數(shù)組末尾添加“@”*/ strcpy(family[j],"@\0"); strcpy(family[i+num+1],"#\0");/*“#”移到數(shù)組末尾*/ strcpy(family[i+num-1],chi);/*在最后一個(gè)“@”前添加新成員*/ end=1;/*end為時(shí)標(biāo)記已添加*/ } else { for(j=i;j>=curpos;j--)/*當(dāng)前位置到數(shù)組最后的全部信息后移一行*/ strcpy(family[j+1],family[j]); strcpy(family[curpos],chi);/*將新結(jié)點(diǎn)存儲(chǔ)到“@”的前一行*/ } if(end==1)/*若end為,則數(shù)組末尾下標(biāo)后移num位*/ i=i+num; for(j=0;j<=i+1;j++)/*將數(shù)組所有信息寫(xiě)入文件*/ { fputs(family[j],fp); fputc('\n',fp);/*一個(gè)信息存一行*/ } fclose(fp);/*關(guān)閉文件*/ printf("添加新成員成功!\n"); } else printf("添加新成員失??!\n"); }}家族成員關(guān)系的相關(guān)查詢(xún)查找一個(gè)家族的鼻祖判斷輸入的姓名是否在該家族中存在,如果存在,則返回該家族的根節(jié)點(diǎn)信息。/*查找一個(gè)家族的祖先*/voidAncesstor(TriTree*t)/*返回樹(shù)的根結(jié)點(diǎn)信息*/{ printf("該家族的祖先為%s\n",t->data);}查找一個(gè)成員的所有祖先路徑查找一個(gè)成員的所有祖先路徑,需要從它的雙親一直向上查找到根結(jié)點(diǎn)。基本思想:對(duì)與結(jié)點(diǎn)t,先判斷它是否是根結(jié)點(diǎn)(根節(jié)點(diǎn)的雙親是NULL),如果是根結(jié)點(diǎn),直接輸出它本身;如果不是,查找它的雙親指針指向的結(jié)點(diǎn),將雙親信息輸出。繼續(xù)查找,直到找到根結(jié)點(diǎn)。/*查找一個(gè)成員的所有祖先*/voidAncesstorPath(TriTree*t){ if(t->parent==NULL)/*若該成員為祖先,則直接輸出*/ printf("%s無(wú)祖先!\n",t->data); else/*否則繼續(xù)查找祖先*/ { printf("%s所有祖先路徑:%s",t->data,t->data); while(t->parent!=NULL)/*若當(dāng)前成員的雙親不是祖先,則繼續(xù)查找*/ { printf("-->%s",t->parent->data); /*訪問(wèn)當(dāng)前成員的雙親*/ t=t->parent;/*繼續(xù)循環(huán)查找*/ } printf("\n"); }}查找一個(gè)成員的雙親基本思想:先判斷結(jié)點(diǎn)t是否是根結(jié)點(diǎn),過(guò)不是根結(jié)點(diǎn),直接輸出該結(jié)點(diǎn)雙親指針的結(jié)點(diǎn)信息;若是根結(jié)點(diǎn),輸出提示信息,結(jié)點(diǎn)無(wú)雙親。/*查找一個(gè)成員的雙親*/voidParent(TriTree*t){ if(t->parent!=NULL)/*若該成員為祖先,則無(wú)雙親*/ printf("%s的雙親為%s\n",t->data,t->parent->data); else printf("%s無(wú)雙親!\n",t->data);}確定一個(gè)成員是第幾代確定一個(gè)成員是第幾代,只要知道從它本身到根結(jié)點(diǎn)包括的祖先個(gè)數(shù)就可。因而對(duì)于跟結(jié)點(diǎn)t,從它本身開(kāi)始一直向上查找到根結(jié)點(diǎn),查找的過(guò)程中用變量count(初值為1)計(jì)數(shù),最后輸出count。/*確定一個(gè)成員是第幾代*/voidGeneration(TriTree*t){ intcount=1;/*計(jì)數(shù)*/ DataTypestr[MAXNUM]; strcpy(str,t->data);/*存儲(chǔ)當(dāng)前信息*/ while(t->parent!=NULL)/*查找其雙親*/ { count++;/*累加計(jì)數(shù)*/ t=t->parent; } printf("%s是第%d代!\n",str,count);}查找一個(gè)成員的兄弟一個(gè)成員的為其雙親除了該成員以外的所有孩子?;舅枷耄簩?duì)于結(jié)點(diǎn)t,先判斷它是否是跟結(jié)點(diǎn),若是根結(jié)點(diǎn),則無(wú)兄弟;若不是根結(jié)點(diǎn),則找到結(jié)點(diǎn)t的雙親。接著判斷雙親的左孩子和左孩子的兄弟是否都存在(若只有左孩子,左孩子就是要查找的這個(gè)成員),如果都不存在,則無(wú)兄弟;如果都存在,對(duì)雙親的左孩子操作。若左孩子不是要查找的這個(gè)成員,則將結(jié)點(diǎn)信息輸出。接下來(lái)查找左孩子的右兄弟,判斷當(dāng)前結(jié)點(diǎn)是否是要查找的這個(gè)成員,若不是,則將結(jié)點(diǎn)信息輸出,繼續(xù)查找當(dāng)前結(jié)點(diǎn)的右兄弟,直到NULL為止。/*查找一個(gè)成員的兄弟*/voidBrothers(TriTree*t,DataTypestr[])/*查找兄弟*/{ if(t->parent!=NULL)/*若該結(jié)點(diǎn)是祖先,則無(wú)兄弟*/ { t=t->parent; /*該結(jié)點(diǎn)的兄弟即為其雙親除該成員以外的所有孩子*/ if(t->lchild&&t->lchild->rchild)/*當(dāng)前結(jié)點(diǎn)的左孩子及其右孩子都存在*/ { printf("%s的所有兄弟有:",str); t=t->lchild; while(t) /*遍歷當(dāng)前成員左孩子的右子樹(shù)*/ { if(strcmp(t->data,str)!=0)/*遍歷右子樹(shù),選擇輸出*/ printf("%s",t->data);/*訪問(wèn)當(dāng)前結(jié)點(diǎn)*/ t=t->rchild; } printf("\n"); } else printf("%s無(wú)兄弟!\n",str); } else printf("%s無(wú)兄弟!\n",str);}查找一個(gè)成員的堂兄弟一個(gè)成員的堂兄弟為其雙親的雙親結(jié)點(diǎn)的所有孩子的孩子(該成員除外).基本思想:如果結(jié)點(diǎn)t的雙親和雙親的雙親(爺爺)都存在,首先考慮爺爺?shù)淖蠛⒆?。如果爺爺?shù)淖蠛⒆硬皇墙Y(jié)點(diǎn)t的雙親,那么爺爺還有其他孩子?,F(xiàn)對(duì)爺爺?shù)淖蠛⒆拥淖蠛⒆釉L問(wèn),如果不是結(jié)點(diǎn)t就輸出。同樣,對(duì)爺爺左孩子的左孩子的右孩子、右孩子的右孩子一直訪問(wèn)下去,直到無(wú)右孩子為止。如果爺爺還有其他孩子,那么就對(duì)爺爺?shù)淖蠛⒆拥挠液⒆印敔數(shù)淖蠛⒆拥挠液⒆拥挠液⒆?-----即對(duì)爺爺?shù)钠渌⒆幼鱿嗤奶幚怼?*查找一個(gè)成員的堂兄弟*/voidConsin(TriTree*t){ intflag=0; TriTree*ch=t; TriTree*temp; if(t->parent&&t->parent->parent)/*當(dāng)前結(jié)點(diǎn)的雙親及其雙親都存在*/ { t=t->parent->parent->lchild;/*當(dāng)前結(jié)點(diǎn)等于其祖先的第一個(gè)孩子*/ while(t) /*存在則繼續(xù)查找*/ { if(strcmp(t->data,ch->parent->data)!=0)/*不是同一結(jié)點(diǎn)*/ { if(t->lchild) /*當(dāng)前結(jié)點(diǎn)存在左孩子*/ { temp=t->lchild; while(temp) /*遍歷當(dāng)前結(jié)點(diǎn)左孩子的右子樹(shù)*/ { if(strcmp(temp->data,ch->data)!=0) { if(!flag)/*第一次輸入時(shí)先輸出下句*/ printf("%s的所有堂兄弟有:",ch->data); printf("%s",temp->data);/*訪問(wèn)當(dāng)前成員*/ flag=1; } temp=temp->rchild;/*繼續(xù)遍歷右孩子*/ } } } t=t->rchild;/*繼續(xù)遍歷右孩子*/ } printf("\n"); } if(!flag)/*標(biāo)志沒(méi)有輸出結(jié)點(diǎn)*/ printf("%s無(wú)堂兄弟!\n",ch->data);}查找一個(gè)成員的所有孩子一個(gè)成員的所有孩子包括左孩子和左孩子的右孩子、左孩子的右孩子的右孩子----直到右孩子為空為止。基本思想:首先判斷結(jié)點(diǎn)t是否有左孩子,如果沒(méi)有,輸出沒(méi)有孩子;如果有左孩子,輸出左孩子的信息,然后判斷左孩子的右孩子是否為空,若不為空(存在右孩子),輸出左孩子的右孩子的信息,接著循環(huán)判斷結(jié)點(diǎn)是否有右孩子,有就輸出,直到右孩子為空。/*查找一個(gè)成員的所有孩子*/voidChildren(TriTree*t)/*遍歷左孩子*/{ if(t->lchild) /*當(dāng)前結(jié)點(diǎn)存在左孩子*/ { printf("%s的所有孩子有:",t->data); t=t->lchild;/*遍歷當(dāng)前成員左孩子的右子樹(shù)*/ while(t) /*不空*/ { printf("%s",t->data);/*訪問(wèn)當(dāng)前成員*/ t=t->rchild; } printf("\n"); } else printf("%s無(wú)孩子!\n",t->data);}/*中序遍歷一棵樹(shù)*/voidInOrder(TriTree*t){ if(t)/*二叉樹(shù)存在*/ { InOrder(t->lchild);/*中序遍歷左子樹(shù)*/ printf("%s",t->data);/*訪問(wèn)成員*/ InOrder(t->rchild);/*中序遍歷右子樹(shù)*/ }}查找一個(gè)成員的子孫后代一個(gè)成員的子孫后代就是其左子樹(shù)上的所有結(jié)點(diǎn),所以對(duì)其左子樹(shù)進(jìn)行中序遍歷即可。/*查找一個(gè)成員的子孫后代*/voidDescendants(TriTree*t)/*遍歷左孩子*/{ if(t->lchild)/*當(dāng)前結(jié)點(diǎn)存在左孩子*/ { printf("%s的所有子孫后代有:",t->data); InOrder(t->lchild);/*中序遍歷當(dāng)前結(jié)點(diǎn)的左右子樹(shù)*/ printf("\n"); } else printf("%s無(wú)后代!\n",t->data);}各軟件之間的調(diào)用方式該軟件各個(gè)模塊的調(diào)用主要是通過(guò)聲明函數(shù),和定義函數(shù)再通過(guò)主函數(shù)調(diào)用實(shí)現(xiàn)的。主函數(shù):/*主控函數(shù)*/intmain(intargc,char*argv[]){ DataTypestr[MAXNUM]="\0",input[40]; inti,j,flag,start=0,pos,tag1,tag2; TriTree*temp,*tree=NULL; while(1) { printf("\t歡迎使用家族關(guān)系查詢(xún)系統(tǒng)!\n"); printf("\t請(qǐng)輸入與之匹配的函數(shù)和參數(shù),如parent(C)\n"); printf("\t1.新建一個(gè)家庭關(guān)系:Create(familyname)參數(shù)為字符串\n"); printf("\t2.打開(kāi)一個(gè)家庭關(guān)系:Open(familyname)參數(shù)為字符串\n"); printf("\t3.添加新成員的信息:Append()無(wú)參數(shù)\n"); printf("\t4.查找一個(gè)成員的祖先:Ancesstor(name)參數(shù)為字符串\n"); printf("\t5.查找一個(gè)成員的祖先路徑:AncesstorPath(name)參數(shù)為字符串\n"); printf("\t6.確定一個(gè)成員是第幾代:Generation(name)參數(shù)為字符串\n"); printf("\t7.查找一個(gè)成員的雙親:Parent(name)參數(shù)為字符串\n"); printf("\t8.查找一個(gè)成員的兄弟:Brothers(name)參數(shù)為字符串\n"); printf("\t9.查找一個(gè)成員的堂兄弟:Consin(name)參數(shù)為字符串\n"); printf("\t10.查找一個(gè)成員的孩子:Children(name)參數(shù)為字符串\n"); printf("\t11.查找一個(gè)成員的子孫后代:Descendants(name)參數(shù)為字符串\n"); printf("\t12.退出系統(tǒng):Exit()無(wú)參數(shù)\n"); gets(input);/*input數(shù)組存放輸入的函數(shù)和參數(shù)*/ j=0,tag1=0,tag2=0; for(i=0;i<strlen(input);i++)/*循環(huán)input數(shù)組*/ { if(input[i]=='(')/*左括號(hào)之前為函數(shù)名*/ { pos=i;/*pos標(biāo)記左括號(hào)位置*/ tag1=1;/*標(biāo)記是否匹配到左括號(hào)*/ } if(input[i+1]==')')/*若下一個(gè)字符不為右括號(hào)*/ tag2=1;/*標(biāo)記為*/ if(tag1==1&&tag2!=1)/*左括號(hào)和右括號(hào)之前為參數(shù)*/ { str[j]=tolower(input[i+1]);/*將參數(shù)存放到str數(shù)組*/ j++;/*并轉(zhuǎn)化為小寫(xiě)字母*/ } input[i]=tolower(input[i]);/*將函數(shù)名轉(zhuǎn)化為小寫(xiě)字母*/ } if(!tag1) /*若沒(méi)匹配到左括號(hào),說(shuō)明只有函數(shù)無(wú)參數(shù)*/ pos=i; /*標(biāo)記為數(shù)組末尾*/ input[pos]='\0';/*將標(biāo)記位置為字符串結(jié)束*/ str[j]='\0'; if(strcmp(input,"create\0")==0)/*函數(shù)名匹配*/ flag=1;/*用flag標(biāo)記*/ elseif(strcmp(input,"open\0")==0) flag=2; elseif(strcmp(input,"append\0")==0) flag=3; elseif(strcmp(input,"ancesstor\0")==0) flag=4; elseif(strcmp(input,"ancesstorpath\0")==0) flag=5; elseif(strcmp(input,"parent\0")==0) flag=6; elseif(strcmp(input,"generation\0")==0) flag=7; elseif(strcmp(input,"brothers\0")==0) flag=8; elseif(strcmp(input,"consin\0")==0) flag=9; elseif(strcmp(input,"children\0")==0) flag=10; elseif(strcmp(input,"descendants\0")==0) flag=11; elseif(strcmp(input,"exit\0")
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年度大型運(yùn)動(dòng)會(huì)安防系統(tǒng)合同
- 2024年度大數(shù)據(jù)分析服務(wù)合同標(biāo)的明細(xì)
- 2024年專(zhuān)用:租賃合同保證金條款匯編
- 2024年度居民住宅鋁合金門(mén)窗安裝工程合同
- 2024年廢舊物資回收協(xié)議
- 2024工程合規(guī)審查中的黑白合同問(wèn)題探討
- 04版智能硬件研發(fā)與制造分包合同
- 2024年國(guó)際貨運(yùn)代理及倉(cāng)儲(chǔ)物流合作合同
- 2024年度5G基站建設(shè)與運(yùn)營(yíng)合作協(xié)議
- 2024年一年級(jí)數(shù)學(xué)老師家長(zhǎng)會(huì)
- 壓力容器及壓力管道課件
- 部編版小學(xué)語(yǔ)文六年級(jí)上冊(cè)《童年》閱讀測(cè)試題及答案(全冊(cè))
- 山東省濟(jì)南市歷城區(qū)2023-2024學(xué)年五年級(jí)上學(xué)期期中數(shù)學(xué)試卷
- 基本消防知識(shí)考試題庫(kù)200題(通用版)
- 23秋國(guó)家開(kāi)放大學(xué)《法律咨詢(xún)與調(diào)解》形考任務(wù)1-4參考答案
- 讀后續(xù)寫(xiě)人與動(dòng)物-天使狗狗的守護(hù)講義 高三英語(yǔ)作文復(fù)習(xí)寫(xiě)作專(zhuān)項(xiàng)
- 課件大班科學(xué)活動(dòng)《有趣的影子》
- 監(jiān)控施工方案四篇
- 某標(biāo)準(zhǔn)件廠冷鐓車(chē)間低壓配電系統(tǒng)及車(chē)間變電所設(shè)計(jì)(超詳細(xì))
- 紫金礦業(yè)污染事件商業(yè)倫理分析
- 體檢指標(biāo)分析課件
評(píng)論
0/150
提交評(píng)論