版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
1、1課程設(shè)計介紹1.1 課程設(shè)計工程簡介家譜是一種以表譜形式,記載一個以血緣關(guān)系為主體的家族世 系繁衍和重要人物事跡的特殊圖書載體.家譜是中國特有的文化 遺產(chǎn),是中華民族的三大文獻之一,屬珍貴的人文資料,對于歷 史學(xué),民俗學(xué),人口學(xué),社會學(xué)和經(jīng)濟學(xué)的深入研究,均有不可 替代的重要功能.本工程對家譜治理進行簡單的模擬,以實現(xiàn)查 看祖先和子孫個人信息、插入家族成員等功能.1.2 課設(shè)題目分析本程序的實質(zhì)是完成對家譜成員信息的建立、查找、插入等 功能.可以首先定義家族成員的數(shù)據(jù)結(jié)構(gòu),然后將每個功能寫成 一個函數(shù)來完成對數(shù)據(jù)的操作,最后完成主函數(shù)以驗證各個函數(shù) 功能并得出運行結(jié)果.本程序包含以下幾個模塊
2、(1)建立家族關(guān)系樹.此模塊將構(gòu)建一個家族關(guān)系,對數(shù)據(jù)初始 化,構(gòu)造關(guān)系樹并錄入數(shù)據(jù)一遍后續(xù)程序使用.(2)添加新成員.此模塊將添加一個新成員,實現(xiàn)對家族關(guān)系的 修改.(3)家族關(guān)系的查詢.此模塊將實現(xiàn)對家族不同關(guān)系的查詢(4)主程序模塊.此模塊實現(xiàn)整個程序的進入和進出, 以及各種 初始化處理.(5)1.3課程題目原理與數(shù)據(jù)結(jié)構(gòu)由于家族的成員之間存在一個對多個的層次結(jié)構(gòu)關(guān)系,所以不能用線性表來表示和實現(xiàn).家譜從形狀上看像一顆倒長的樹,所 以用樹結(jié)構(gòu)來表示比較適宜.樹形結(jié)構(gòu)是一類非常重要的非線性 數(shù)據(jù)結(jié)構(gòu),直觀看來樹是以分支關(guān)系定義的層次結(jié)構(gòu).因此本課程設(shè)計可以采用的數(shù)據(jù)結(jié)構(gòu)有樹狀結(jié)構(gòu)和隊列.樹
3、狀 結(jié)構(gòu)采用三叉鏈表來實現(xiàn),隊列采用鏈?zhǔn)疥犃袑崿F(xiàn).1.4功能分析說明圖家族關(guān)系查詢系統(tǒng)退出系統(tǒng)按關(guān)系查找各個家庭成 員添加一個家庭成員翻開一個家族關(guān)系建立一個家族關(guān)系查找成員的子孫后代查找一個成員的孩子查找成員的堂兄弟查找一個成員的兄弟查找一個成員雙親查找成員是第幾代查找成員祖先路徑查找一個成員的祖先2分析與實現(xiàn)2.1 根本數(shù)據(jù)結(jié)構(gòu)和棧隊的操作2.1.1 結(jié)點根本數(shù)據(jù)結(jié)構(gòu)和鏈隊的定義/*家族關(guān)系樹實現(xiàn)*/#include <string.h>#include <malloc.h>#include<limits.h>#include<stdio.h>
4、;#include<stdlib.h>#include<io.h>#include<math.h>#include<process.h># define TRUE 1# define FALSE 0# define OK 1# define ERROR -1# define INFEASIBLE -1 typedef char DataType;# define MAXNUM 20typedef struct TriTNode/*樹的三叉鏈表存儲結(jié)構(gòu)*/(DataType dataMAXNUM;struct TriTNode *parent; /
5、* 雙親 */struct TriTNode *lchild;/* 左孩子*/struct TriTNode *rchild; /* 右孩子 */TriTree;typedef struct Node/*隊列的結(jié)點結(jié)構(gòu)*/(TriTree *info;struct Node *next;Node;typedef struct/*鏈接隊列類型定義*/(struct Node *front; /* 頭指針 */struct Node *rear;/* 尾指針 */LinkQueue;DataType fnameMAXNUM,family50MAXNUM; /* 全局變量*/2.1.2 鏈隊的根本操
6、作LinkQueue *LQueueCreateEmpty( )/* 建立一個空隊列 */ (LinkQueue *plqu=(LinkQueue *)malloc( sizeof(LinkQueue);if (plqu!=NULL)plqu->front=plqu->rear=NULL;else(printf("內(nèi)存缺乏! n");return NULL;return plqu;int LQueueIsEmpty(LinkQueue *plqu)/* 判斷鏈接表示隊列是否為 空隊列*/return(plqu->front=NULL);)void LQue
7、ueEnQueue(LinkQueue *plqu,TriTree *x)/* 進隊列*/ (Node *p=(Node *)malloc( sizeof(Node);if(p=NULL)printf("內(nèi)存分配失敗! n");else(p->info=x;p->next=NULL;if(plqu->front=NULL) /* 原來為空隊*/plqu->front=p;elseplqu->rear->next=p;plqu->rear=p;)int LQueueDeQueue(LinkQueue *plqu,TriTree *x)
8、/* 出隊列*/(Node *p;if (plqu->front=NULL)(printf("隊列空! n");return ERROR;) else(p=plqu->front;x=p->info;plqu->front=plqu->front->next;free(p);return OK;)TriTree *LQueueGetFront(LinkQueue *plqu) /* 在非空隊列中求隊 頭元素*/return(plqu->front->info); )2.2 建立家族關(guān)系2.2.1 建立家族關(guān)系弁存入文件根本思想
9、:首先輸入家族關(guān)系的名稱,以此名稱為文件名,建立文本文件接下來按層次輸入結(jié)點信息,輸入一個在文件 中寫入一行同時將輸入的信息保存到二位字符數(shù)組family中.字符數(shù)組family是全局變量,存儲 臨時信息.注意,輸入時每個結(jié)點信息占一行,一個結(jié)點有多個 兄弟,以“ 作為兄弟結(jié)束標(biāo)志,結(jié)點假設(shè)無孩子,直接以“ 代替.依次輸入各節(jié)點信息,以“ #"作為結(jié)束標(biāo)志.最后使用 函數(shù)CreateTriTree建立家族關(guān)系樹.TriTree *Create(DataType familynameMAXNUM) /* 建立家族關(guān) 系并存入文件*/int i=0;/* i限制family數(shù)組下標(biāo)*/D
10、ataType ch,strMAXNUM;/* ch 存儲輸入的 y或n, str存儲輸入的字符用*/TriTree *t;FILE *fp;strcpy(fname,familyname); /*以家族名為文本文件名存儲*/ strcat(fname".txt");fp=fopen(fname,"r");/*以讀取方式翻開文件*/if(fp)/*文件已存在*/fclose(fp);printf("%s的家族關(guān)系已存在!重新建立請按“Y'直接翻開請按 “Nn",familyname);ch=getchar();getchar(
11、);/* 接收回車*/if(ch='N'|ch='n')t=Open(familyname);/* 直接翻開*/ return t;if(!fp|ch='Y'|ch=y)/*重新建立,執(zhí)行以下操作*/fp=fopen(fname,"w"); /*以寫入方式翻開文件,不存在那么新建*/printf("請按層次輸入結(jié)點,每個結(jié)點信息占一行n");printf("兄弟輸入結(jié)束以“)為標(biāo)志,結(jié)束標(biāo)志為"#n."); gets(str);fputs(str,fp);fputc('
12、n',fp);strcpy(familyi,str); /*將成員信息存儲到字符數(shù)組中*/ i+;/* family數(shù)組下標(biāo)后移*/while(str0!='#') printf(". ");/*以點提示符提示繼續(xù)輸入*/gets(str);fputs(str,fp);/*寫到文件中,每個信息占一行*/fputc('n',fp);strcpy(familyi,str); /*將成員信息存儲到字符數(shù)組中*/i+;/* family數(shù)組下標(biāo)后移*/)fclose(fp);/* 關(guān)閉文件*/t=TriTreeCreate(); /*根據(jù)fa
13、mily數(shù)組信息創(chuàng)立三叉樹*/ printf("家族關(guān)系已成功建立!n");return t;/* 返回樹*/)2.2.2 建立家族關(guān)系樹根本思想:采用指針數(shù)組作為指針,保存輸入的結(jié)點地址.隊列的尾指針指向當(dāng)前結(jié)點.頭指針指向當(dāng)前結(jié)點的雙親結(jié)點. 輸入的結(jié)點信息已存儲在字符數(shù)組family中.將信息復(fù)制到字符串?dāng)?shù)組“ ch中,如果"ch"不是",那么 建立一個新結(jié)點.假設(shè)新結(jié)點是第一個結(jié)點,那么它是根結(jié)點,將其 入隊,指針tree指向這個根節(jié)點;如果不是根結(jié)點,那么將當(dāng)前結(jié) 點鏈接到雙親結(jié)點上,即當(dāng)前結(jié)點的雙親指針就是隊頭元素,然 后將當(dāng)前結(jié)點
14、入隊列.接著判斷flag的值,如果flag=0 ,表示 當(dāng)前結(jié)點沒有左孩子,那么當(dāng)前結(jié)點就是雙親的左孩子.否那么, 當(dāng)前結(jié)點就是雙親的右孩子.用指針root指向剛剛?cè)腙牭慕Y(jié)點.繼續(xù)復(fù)制數(shù)組family的下個元素.如果“ ch是那么flag=0 (由于“后面的第一個孩子為左孩子),同時判斷“是否是 第一次出現(xiàn),如果是第一次,那么令標(biāo)志 star=1 ;如果不是第一次 出現(xiàn).那么出隊列,root指向隊頭元素(實際上root總是指向雙 親結(jié)點).繼續(xù)復(fù)制family的下一個元素.知道遇到“ #"結(jié)束. 函數(shù)返回指針tree./*建立家族關(guān)系樹*/TriTree *TriTreeCreate
15、() TriTree *t,*x=NULL,*tree,*root=NULL;LinkQueue *q=LQueueCreateEmpty()/* 建立一個空的隊列,存儲指向樹的指針*/int i=0,flag=0,start=0;DataType strMAXNUM;strcpy(str,familyi);i+;while(str0!= '#')while(str0!= ')if (root=NULL)/*/*存放family數(shù)組中信息*/*復(fù)制*/* family數(shù)組下標(biāo)后移*/*沒遇到結(jié)束標(biāo)志繼續(xù)循環(huán)*/沒遇到兄弟輸入結(jié)束標(biāo)志繼續(xù)*/*空樹*/root=(TriT
16、ree *)malloc( sizeof(TriTree);/* 申請空問*/strcpy(root->data,str);root->parent=NULL;root->lchild=NULL;root->rchild=NULL;LQueueEnQueue(q,root);/*將root存入隊列*/tree=root;else/*不為空樹*/t=(TriTree *)malloc( sizeof(TriTree); /* 申請空間*/strcpy(t->data,str);t->lchild=NULL;t->rchild=NULL;t->par
17、ent=LQueueGetFront(q);/*當(dāng)前結(jié)點的雙親為隊頭元素*/LQueueEnQueue(q,t);/* 入隊*/if(!flag) /* flag為,當(dāng)前結(jié)點沒有左孩子*/root->lchild=t;else /* flag為,當(dāng)前結(jié)點已有左孩子*/root->rchild=t;root=t;/* root指向新的結(jié)點t */)flag=1;/*標(biāo)記當(dāng)前結(jié)點已有左孩子*/strcpy(str,familyi);i+;)if(start!=0)/*標(biāo)記不是第一次出現(xiàn) “ */(LQueueDeQueue(q,x);/* 出隊*/if (q->front!=NU
18、LL)root=LQueueGetFront(q);/* root 為隊頭元素 */)start=1;/*標(biāo)記已出現(xiàn)過 “ */flag=0;/*密面的結(jié)點一定為左孩子*/strcpy(str,familyi);i+;)return tree;/* 返回樹*/)2.3 翻開一個家族關(guān)系首先輸入家族關(guān)系名,以家族名為文件名翻開文件,如果家 族關(guān)系不存在,返回空;如果存在,文件翻開,讀取文件.將文 件的每行信息依次存儲在數(shù)組family 中./*翻開一個家族關(guān)系*/TriTree *Open(DataType familynameMAXNUM)(int i=0,j=0;DataType ch;FI
19、LE *fp;TriTree *t;strcpy(fname,familyname); /*以家族名為文本文件名存儲*/ strcat(fname".txt");fp=fopen(fname,"r");/*以讀取方式翻開文件*/if(fp=NULL)/* 文件不存在 */(printf("%s 的家族關(guān)系不存在! n",familyname);return NULL;) else ( ch=fgetc(fp); while(ch!=EOF) (if (ch!='n') (familyij=ch;組中*/j+;) els
20、e (family皿='0' i+;j=0;) ch=fgetc(fp);) fclose(fp); t=TriTreeCreate(family);/*按字符讀取文件*/*讀到文件尾結(jié)束*/* ch不為一個結(jié)點信息的結(jié)尾*/*將文件信息存儲到family數(shù)/*字符串結(jié)束標(biāo)志*/* family數(shù)組行下標(biāo)后移*/* family數(shù)組列下標(biāo)歸零*/*繼續(xù)讀取文件信息*/*關(guān)閉文件*/*調(diào)用函數(shù)建立三叉鏈表*/printf("家族關(guān)系已成功翻開!n");return t;)2.4 在家族關(guān)系中查找一個成員是否存在用遞歸算法實現(xiàn).如果樹空,返回 NULL如果根節(jié)點
21、就是要 查找的成員,返回根節(jié)點;否那么,遞歸查找它的左右子樹./*查找一個成員是否存在*/TriTree *Search(TriTree *t,DataType str)(TriTree *temp; if(t=NULL)/*如果樹空那么返回NULL */return NULL;elseif(strcmp(t->data,str)=0) /* 如果找到返回該成員指針 */ return t;else/*如果沒找到遍歷左右子樹進行查找*/temp=Search(t->lchild,str); /* 遞歸查找 */if (temp)/*結(jié)點不空那么查找*/return(Search(t
22、->lchild,str);elsereturn(Search(t->rchild,str);2.5 向家族中添加一個新成員根本思想:添加的新成員要根據(jù)其雙親確定其在家族中的位 置.首先判斷該雙親是否在此家族關(guān)系中,假設(shè)存在那么查找其雙 親,將新結(jié)點插入其雙親的最后一個孩子之后;假設(shè)沒有孩子,那么 直接作為左孩子插入.以寫入的方式翻開文件,如果成功翻開, 那么更新family數(shù)組中的信息,并查找新成員的雙親所在位置和其 對應(yīng)的“個數(shù),如果“ 個數(shù)小于雙親位置,那么添加“ 實質(zhì)相等,新成員不插入到最后 之前.最后將family數(shù)組 中信息寫入文件保存,關(guān)閉文件./*添加一個新成員*/
23、void Append(TriTree *t)int i=0,j,parpos=1,curpos,num,end=0,count=-1;DataType chiMAXNUM,parMAXNUM; /* 存儲輸入的孩子 和其雙親結(jié)點*/TriTree *tpar,*temp;FILE *fp;printf("請輸入要添加的成員和其父親,以回車分隔!n.");gets(chi);printf(". ");/*以點提示符提示繼續(xù)輸入*/gets(par);tpar=Search(t,par); /*查找雙親結(jié)點是否存在*/if(!tpar)printf(&qu
24、ot;%s該成員不存在! n");else/*存在那么添加其孩子*/(temp=(TriTree *)malloc( sizeof(TriTree);/* 申請空間 */ temp->parent=tpar;strcpy(temp->data,chi);temp->lchild=NULL;/*新結(jié)點左右孩子置空*/temp->rchild=NULL; if(tpar->lchild)/*成員存在左孩子*/(tpar=tpar->lchild; /*遍歷當(dāng)前成員左孩子的右子樹*/*當(dāng)前結(jié)點右孩子存在*/*繼續(xù)遍歷右孩子*/*將新結(jié)點添/*沒有孩子那么
25、直接添加*/*以寫入方式翻開文件*/while(tpar->rchild) tpar=tpar->rchild;tpar->rchild=temp;加到所有孩子之后*/ elsetpar->lchild=temp; fp=fopen(fname,"w");if(fp)(while(strcmp(par,familyi)!=0&&familyi0!= '#') (/*查找雙親在數(shù)組/* parpos 計數(shù) */* family數(shù)組行下標(biāo)后移*/* family數(shù)組行下標(biāo)歸*/*查找勺個/* count累加個數(shù)*/*說明此
26、“fif(familyi0!= '') 中位置*/parpos+;i+;i=0;while(familyi0!= '#')(if(familyi0= '')數(shù),第一個不計*/count+;if(count=parpos)其前一個“之前為par的孩子*/curpos=i;i+;)if (count<parpos)(num=parpos-count;for(j=i;j<=i+num;j+)/* curpos計當(dāng)前位置*/ /* family數(shù)組行下標(biāo)后移*/*"遨小于parpo嗷*/*添加“1數(shù)為num */*從數(shù)組末尾添加“
27、*/strcpy(familyj, "0");strcpy(familyi+num+1, "#0");/*"移到數(shù)組末尾*/strcpy(familyi+num-1,chi); /* 在最后一個 “ 前添加新成員*/end=1;/* end為時標(biāo)記已添加*/) else (for(j=i;j>=curpos;j-)/* 當(dāng)前位置到數(shù)組最后的全部信息后移一行*/strcpy(familyj+1,familyj);strcpy(familycurpos,chi); /* 將新結(jié)點存儲到“的前一行*/)if (end=1) /*假設(shè)en狽,那么
28、數(shù)組末尾下標(biāo)后移num位*/i=i+num;for(j=0;j<=i+1;j+)/*將數(shù)組所有信息寫入文件*/(fputs(familyj,fp);fputc('n',fp);/* 一個信息存一行 */)fclose(fp);/* 關(guān)閉文件 */printf("添加新成員成功!n");)elseprintf("添加新成員失敗!n");)2.6家族成員關(guān)系的相關(guān)查詢2.6.1 查找一個家族的鼻祖判斷輸入的姓名是否在該家族中存在,如果存在,那么返回 該家族的根節(jié)點信息./*查找一個家族的祖先*/void Ancesstor(TriTre
29、e *t)/* 返回樹的根結(jié)點信息 */(printf("該家族的祖先為 %sn",t->data);)2.6.2 查找一個成員的所有祖先路徑查找一個成員的所有祖先路徑,需要從它的雙親一直向上查 找到根結(jié)點.根本思想:對與結(jié)點t,先判斷它是否是根結(jié)點(根節(jié)點的雙親是 NULL ,如果是根結(jié)點,直接輸出它本身;如果不是,查找它的 雙親指針指向的結(jié)點,將雙親信息輸出.繼續(xù)查找,直到找到根 結(jié)點0/*查找一個成員的所有祖先*/void AncesstorPath(TriTree *t)(if(t->parent=NULL) /*假設(shè)該成員為祖先,那么直接輸出*/pri
30、ntf("%s 無祖先! n",t->data);else/*否那么繼續(xù)查找祖先*/(printf("%s 所有祖先路徑:%s",t->data,t->data);while(t->parent!=NULL) /*假設(shè)當(dāng)前成員的雙親不是祖先, 那么繼續(xù)查找*/(printf(" -> %s",t->parent->data); /* 訪問當(dāng)前成員的 雙親*/t=t->parent;/*繼續(xù)循環(huán)查找*/)printf("n");)2.6.3 查找一個成員的雙親根本思想:
31、先判斷結(jié)點t是否是根結(jié)點,過不是根結(jié)點,直接輸出該結(jié)點雙親指針的結(jié)點信息;假設(shè)是根結(jié)點,輸出提示信 息,結(jié)點無雙親./*查找一個成員的雙親*/void Parent(TriTree *t)if(t->parent!=NULL) /*假設(shè)該成員為祖先,那么無雙親*/ printf("%s 的雙親為 %sn",t->data,t->parent->data);elseprintf("%s 無雙親! n",t->data);)2.6.4 確定一個成員是第幾代確定一個成員是第幾代,只要知道從它本身到根結(jié)點包括的 祖先個數(shù)就可.因而對
32、于跟結(jié)點t,從它本身開始一直向上查找 到根結(jié)點,查找的過程中用變量count (初值為1)計數(shù),最后輸 出 count./*確定一個成員是第幾代*/void Generation(TriTree *t)int count=1;/* 計數(shù)*/DataType strMAXNUM;strcpy(str,t->data);/* 存儲當(dāng)前信息*/while (t->parent!=NULL) /* 查找其雙親 */ (count+;/*累加計數(shù)*/t=t->parent;printf( "%s 是第 d 代! n" ,str,count);2.6.5 查找一個成員
33、的兄弟一個成員的為其雙親除了該成員以外的所有孩子.根本思想:對于結(jié)點t,先判斷它是否是跟結(jié)點,假設(shè)是根 結(jié)點,那么無兄弟;假設(shè)不是根結(jié)點,那么找到結(jié)點t的雙親.接著判 斷雙親的左孩子和左孩子的兄弟是否都存在(假設(shè)只有左孩子,左 孩子就是要查找的這個成員),如果都不存在,那么無兄弟;如果 都存在,對雙親的左孩子操作.假設(shè)左孩子不是要查找的這個成 員,那么將結(jié)點信息輸出.接下來查找左孩子的右兄弟,判斷當(dāng)前 結(jié)點是否是要查找的這個成員,假設(shè)不是,那么將結(jié)點信息輸出,繼 續(xù)查找當(dāng)前結(jié)點的右兄弟,直到NUL的止./*查找一個成員的兄弟*/void Brothers(TriTree *t,DataType
34、 str) /* 查找兄弟*/ (if(t->parent!=NULL) /*假設(shè)該結(jié)點是祖先,那么無兄弟*/ (t=t->parent;/*該結(jié)點的兄弟即為其雙親除該成員以外的所有孩子*/if(t->lchild&&t->lchild->rchild) /* 當(dāng)前結(jié)點的左孩子 及其右孩子都存在*/(printf("%s的所有兄弟有:,str);t=t->lchild;while(t)/*遍歷"當(dāng)前成員左孩子的右子樹*/(if(strcmp(t->data,str)!=0) /* 遍歷右子樹,選擇 輸出*/print
35、f("%s ",t->data); /* 訪問當(dāng)前結(jié)點*/t=t->rchild;)printf( "n");)elseprintf("%s 無兄弟! n",str);)elseprintf("%s 無兄弟! n",str);)2.6.6 查找一個成員的堂兄弟一個成員的堂兄弟為其雙親的雙親結(jié)點的所有孩子的孩 子(該成員除外).根本思想:如果結(jié)點t的雙親和雙親的雙親(爺爺)都存在, 首先考慮爺爺?shù)淖蠛⒆?如果爺爺?shù)淖蠛⒆硬皇墙Y(jié)點t的雙親,那么爺爺還有其他孩子.現(xiàn)對爺爺?shù)淖蠛⒆拥淖蠛⒆釉L問,如果 不是結(jié)點t
36、就輸出.同樣,對爺爺左孩子的左孩子的右孩子、右 孩子的右孩子一直訪問下去,直到無右孩子為止.如果爺爺還有 其他孩子,那么就對爺爺?shù)淖蠛⒆拥挠液⒆印敔數(shù)淖蠛⒆拥挠?孩子的右孩子-即對爺爺?shù)钠渌⒆幼鱿嗤奶幚?/*查找一個成員的堂兄弟*/void Consin(TriTree *t)int flag=0;TriTree *ch=t;TriTree *temp;if(t->parent&&t->parent->parent)/* 當(dāng)前結(jié)點的雙親及其雙親 都存在*/t=t->parent->parent->lchild;/*當(dāng)前結(jié)點等于其祖先的第
37、 一個孩子*/while(t)/*存在那么繼續(xù)查找*/if (strcmp(t->data,ch->parent->data)!=0/* 不是同一結(jié) 點*/(if(t->lchild)/*當(dāng)前結(jié)點存在左孩子*/(temp=t->lchild;while(temp)/* 遍歷當(dāng)前結(jié)點左孩子的右子樹*/(if (strcmp(temp->data,ch->data)!=0)(if(!flag)/* 第一次輸入時先輸出下旬*/printf("%s的所有堂兄弟有: ",ch->data);printf( "%s "
38、,temp->data)/* 訪問當(dāng) 前成員*/flag=1;temp=temp->rchild;/* 繼續(xù)遍歷右孩子*/t=t->rchild;/*繼續(xù)遍歷右孩子*/printf("n");if(!flag)/*標(biāo)志沒有輸出結(jié)點*/printf("%s 無堂兄弟! n",ch->data);2.6.7 查找一個成員的所有孩子一個成員的所有孩子包括左孩子和左孩子的右孩子、左孩子 的右孩子的右孩子直到右孩子為空為止.根本思想:首先判斷結(jié)點t是否有左孩子,如果沒有,輸出 沒有孩子;如果有左孩子,輸出左孩子的信息,然后判斷左孩子 的右孩
39、子是否為空,假設(shè)不為空(存在右孩子),輸出左孩子的右孩子的信息,接著循環(huán)判斷結(jié)點是否有右孩子,有就輸出,直到 右孩子為空./*查找一個成員的所有孩子*/void Children(TriTree *t)/* 遍歷左孩子 */(if(t->lchild)/*當(dāng)前結(jié)點存在左孩子*/(printf("%s 的所有孩子有:",t->data);t=t->lchild;/*遍歷當(dāng)前成員左孩子的右子樹*/while(t)/* 不空*/(printf("%s ",t->data);/* 訪問當(dāng)前成員 */ t=t->rchild;prin
40、tf("n");else printf("%s 無孩子! n",t->data);/*中序遍歷一棵樹*/void InOrder(TriTree *t)(if(t)/*二叉樹存在*/(InOrder(t->lchild);/* 中序遍歷左子樹 */printf("%s ",t->data);/* 訪問成員 */InOrder(t->rchild);/* 中序遍歷右子樹 */2.6.8 查找一個成員的子孫后代一個成員的子孫后代就是其左子樹上的所有結(jié)點,所以對 其左子樹進行中序遍歷即可./*查找一個成員的子孫后代*
41、/void Descendants(TriTree *t)/* 遍歷左孩子 */(if(t->lchild)/*當(dāng)前結(jié)點存在左孩子*/(printf("%s的所有子孫后代有:",t->data);InOrder(t->lchild); /*中序遍歷當(dāng)前結(jié)點的左右子樹*/ printf("n");else printf("%s 無后代! n",t->data);2.6.9 件之間的調(diào)用方式該軟件各個模塊的調(diào)用主要是通過聲明函數(shù),和定義函數(shù) 再通過主函數(shù)調(diào)用實現(xiàn)的.主函數(shù):/*主控函數(shù)*/int main(int
42、argc,char* argv口)(DataType strMAXNUM= "0",input40;int i,j,flag,start=0,pos,tag1,tag2;TriTree *temp,*tree=NULL;while(1)printf"t歡迎使用家族關(guān)系查詢系統(tǒng)!n"printf"t請輸入與之匹配的函數(shù)和參數(shù),如 parentCn"Create(familyname)Open(familyname)Append()Ancesstor(name)printf"t 1.新建一個家庭關(guān)系: 參數(shù)為字符串n"
43、printf"t 2.翻開一個家庭關(guān)系: 參數(shù)為字符串n"printf"t 3.添加新成員的信息: 無參數(shù)n"printf"t 4.查找一個成員的祖先: 參數(shù)為字符串n"printf("t 5.查找一個成員的祖先路徑: AncesstorPath(name)參數(shù)為字符串 n");printf("t 6.確定一個成員是第幾代:Generation(name)參數(shù)為字符串n");printf("t 7.查找一個成員的雙親:Parent(name)參數(shù)為字符串n");printf(
44、"t 8.查找一個成員的兄弟:Brothers(name)參數(shù)為字符串n");printf("t 9.查找一個成員的堂兄弟:Consin(name)參數(shù)為字符串n");printf("t10.查找一個成員的孩子:Children(name)參數(shù)為字符串n");printf( "t11.查找一個成員的子孫后代:Descendants(name)參數(shù)為字符串n");printf("t12.退出系統(tǒng):Exit()無參數(shù)n?");gets(input); /* input數(shù)組存放輸入的函數(shù)和參數(shù)*/j=
45、0,tag1=0,tag2=0;for(i=0;i<strlen(input);i+) /* 循環(huán)input數(shù)組*/if (inputi= '(')pos=i;tag1=1;if (inputi+1= ')') tag2=1;if (tag1=1&&tag2!=1)參數(shù)*/strj=tolower(inputi+1);*/j+;inputi=tolower(inputi);寫字母*/*左括號之前為函數(shù)名*/* pos標(biāo)記左括號位置*/*標(biāo)記是否匹配到左括號*/*假設(shè)下一個字符不為右括號*/*標(biāo)記為*/*左括號和右括號之前為/*將參數(shù)存放到s
46、tr數(shù)組/*并轉(zhuǎn)化為小寫字母*/*將函數(shù)名轉(zhuǎn)化為小if(!tag1) /*假設(shè)沒匹配到左括號,說明只有函數(shù)無參數(shù)*/pos=i; /*標(biāo)記為數(shù)組末尾*/inputpos= '0'/*將標(biāo)記位置為字符串結(jié)束*/strj= '0'if (strcmp(input,"create0")=0)/* 函數(shù)名匹酉己 */flag=1;/* 用 flag 標(biāo)記*/else if (strcmp(input,"open0")=0)flag=2;else if (strcmp(input,"append0")=0)fla
47、g=3;elseif (strcmp(input,"ancesstor0"(=0)flag=4;elseif(strcmp(input,"ancesstorpath0')=0)flag=5;else if (strcmp(input,"parent0")=0)flag=6;elseif(strcmp(input,"generation0")=0)flag=7;elseif (strcmp(input,"brothers0")=0)flag=8;elseif (strcmp(input,"
48、consin0")=0)flag=9;else if (strcmp(input,"children0" )=0)flag=10;elseif (strcmp(input,"descendants0)=0)flag=11;else if(strcmp(input,"exit0"尸=0)flag=12;else/*無匹配那么重新輸入*/(printf("無匹配的函數(shù),請重新輸入!n");continue;)if (!(flag=1|flag=2|flag=12)&&start=0) /*如果第一次輸入
49、函數(shù)不是建立、翻開或退出,那么重 新輸入*/printf("請先建立或翻開一個家族關(guān)系!n");continue;)start=1;/*標(biāo)記不是第一次輸入input */if(flag>=4&&flag<=11) /*函數(shù)需要字符串型參數(shù)name */ (temp=Search(tree,str)/* 假設(shè)存在那么返回結(jié)點 */if(!temp)/*假設(shè)不存在那么返回*/(printf("該成員不存在! n"); continue;)switch(flag)/*根據(jù)flag標(biāo)記調(diào)用函數(shù)*/(case1:tree=Create(
50、str); break;case2:tree=Open(str); break;case3:Append(tree); break;case4:Ancesstor(tree); break;case5:AncesstorPath(temp); break;case6:Parent(temp); break;case7:Generation(temp); break;case8:Brothers(temp,str);break;case9:Consin(temp); break;case10:Children(temp); break;case11:Descendants(temp); break;case12: exit(OK);return 0;3調(diào)試結(jié)果調(diào)試運行后,顯示主界面數(shù)用與ust- 8配八±'-12 3:第一 i 的直查鹿查杳一查查查退 4 5 6789 0 12二新二二二二系罡去成成質(zhì)成成成成L .匹個個成個個個個統(tǒng)先先幾親弟兄子孫 系vnl心雙兄堂孩子 一¥(d_1geTEii口囚巖巖巖巖巖巖貝徑;路代: 代 弟:后Ancesstor(nane) AncesstorPath(na
溫馨提示
- 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度城市社區(qū)公共洗浴設(shè)施承包服務(wù)合同4篇
- 二零二五年度門窗五金件品牌設(shè)計與推廣合同3篇
- 2025年度門面房租賃合同風(fēng)險評估及應(yīng)對策略4篇
- 2025年度海外勞務(wù)輸出合同風(fēng)險評估與合規(guī)指南3篇
- 2025年度廚房設(shè)備節(jié)能改造工程承包合同4篇
- 2025年度高端個人二手車品牌轉(zhuǎn)讓合同模板3篇
- 二零二五年度水利工程承包合同范本集4篇
- 2025年度智能家電產(chǎn)品批量采購合同書范本4篇
- 二零二五版新能源汽車動產(chǎn)抵押貸款合同
- 2025年度鋁灰處理項目環(huán)保驗收服務(wù)合同4篇
- 化學(xué)-廣東省廣州市2024-2025學(xué)年高一上學(xué)期期末檢測卷(一)試題和答案
- 2025四川中煙招聘高頻重點提升(共500題)附帶答案詳解
- 2025年云南大理州工業(yè)投資(集團)限公司招聘31人管理單位筆試遴選500模擬題附帶答案詳解
- 風(fēng)電危險源辨識及控制措施
- 《教師職業(yè)道德與政策法規(guī)》課程教學(xué)大綱
- EHS工程師招聘筆試題與參考答案(某大型央企)2024年
- 營銷策劃 -麗亭酒店品牌年度傳播規(guī)劃方案
- 兒童傳染病預(yù)防課件
- 護理組長年底述職報告
- 集裝箱活動房供需合同
- 山西省2022年中考道德與法治真題試卷(含答案)
評論
0/150
提交評論