數(shù)據(jù)結(jié)構(gòu)課程設(shè)計家族關(guān)系查詢系統(tǒng)_第1頁
數(shù)據(jù)結(jié)構(gòu)課程設(shè)計家族關(guān)系查詢系統(tǒng)_第2頁
數(shù)據(jù)結(jié)構(gòu)課程設(shè)計家族關(guān)系查詢系統(tǒng)_第3頁
數(shù)據(jù)結(jié)構(gòu)課程設(shè)計家族關(guān)系查詢系統(tǒng)_第4頁
數(shù)據(jù)結(jié)構(gòu)課程設(shè)計家族關(guān)系查詢系統(tǒng)_第5頁
已閱讀5頁,還剩23頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quá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ì)是完成對家譜成員信息的建立、查找、插入等功能??梢允紫榷x家族成員的數(shù)據(jù)結(jié)構(gòu),然后將每個功能寫成一個函數(shù)來完成對數(shù)據(jù)的操作,最后完成主函數(shù)以驗證各個函數(shù)功能并得出運行結(jié)果。本程序包含以下幾個模塊(1) 建

2、立家族關(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)和隊列。樹狀結(jié)構(gòu)采用

3、三叉鏈表來實現(xiàn),隊列采用鏈式隊列實現(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>#in

4、clude<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 -1typedef char DataType;#define MAXNUM 20typedef struct TriTNode/* 樹的三叉鏈表存儲結(jié)構(gòu)*/ DataType dataMAXNUM;struct TriTNode *parent;/* 雙親*/struc

5、t 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 鏈隊的基本操作LinkQueue *

6、LQueueCreateEmpty( )/* 建立一個空隊列*/ LinkQueue *plqu=(LinkQueue *)malloc(sizeof(LinkQueue); if (plqu!=NULL) plqu->front=plqu->rear=NULL; elseprintf("內(nèi)存不足!n");return NULL; return plqu;int LQueueIsEmpty(LinkQueue *plqu)/* 判斷鏈接表示隊列是否為空隊列*/ return(plqu->front=NULL);void LQueueEnQueue(Link

7、Queue *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; else plqu->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)系 建立家族關(guān)系并存入文件 基本思想:首先輸入家族關(guān)系的名稱,以此名稱為

9、文件名,建立文本文件接下來按層次輸入結(jié)點信息,輸入一個在文件中寫入一行同時將輸入的信息保存 到二位字符數(shù)組family中。字符數(shù)組family是全局變量,存儲臨時信息 . 注意,輸入時每個結(jié)點信息占一行,一個結(jié)點有多個兄弟,以“”作為兄弟結(jié)束標(biāo)志,結(jié)點若無孩子,直接以“”代替。依次輸入各節(jié)點信息,以“#” 作為結(jié)束標(biāo)志。最后使用函數(shù)CreateTriTree建立家族關(guān)系樹.lixianliguoyu liguojun liguoqiangliyongzhi liyongrui liyongmingliwende liwenjia TriTree *Create(DataType familyn

10、ameMAXNUM)/* 建立家族關(guān)系并存入文件*/int i=0; /* i控制family數(shù)組下標(biāo)*/DataType 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)系已存在!重新建立

11、請按“Y”,直接打開請按“N”n",familyname);ch=getchar();getchar(); /* 接收回車*/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("兄弟輸

12、入結(jié)束以“”為標(biāo)志,結(jié)束標(biāo)志為“#”n. ");gets(str);fputs(str,fp);fputc('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ù)組

13、中*/i+; /* family數(shù)組下標(biāo)后移*/fclose(fp); /* 關(guān)閉文件*/t=TriTreeCreate(); /* 根據(jù)family數(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é)點。若新結(jié)點是第一個結(jié)點,則它是根結(jié)點,將其入隊,指針tr

14、ee指向這個根節(jié)點;如果不是根結(jié)點,則將當(dāng)前結(jié)點鏈接到雙親結(jié)點上,即當(dāng)前結(jié)點的雙親指針就是隊頭元素,然后將當(dāng)前結(jié)點入隊列。接著判斷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ù)返

15、回指針tree。 /* 建立家族關(guān)系樹*/TriTree *TriTreeCreate()TriTree *t,*x=NULL,*tree,*root=NULL;LinkQueue *q=LQueueCreateEmpty();/* 建立一個空的隊列,存儲指向樹的指針*/int i=0,flag=0,start=0;DataType strMAXNUM; /* 存放family數(shù)組中信息*/strcpy(str,familyi); /* 復(fù)制*/i+; /* family數(shù)組下標(biāo)后移*/while(str0!='#') /* 沒遇到結(jié)束標(biāo)志繼續(xù)循環(huán)*/while(str0!=&

16、#39;') /* 沒遇到兄弟輸入結(jié)束標(biāo)志繼續(xù)*/if(root=NULL) /* 空樹*/root=(TriTree *)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

17、(t->data,str);t->lchild=NULL;t->rchild=NULL;t->parent=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(star

18、t!=0) /* 標(biāo)記不是第一次出現(xiàn)“”*/LQueueDeQueue(q,x); /* 出隊*/if(q->front!=NULL)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)系*

19、/TriTree *Open(DataType familynameMAXNUM)int i=0,j=0;DataType ch;FILE *fp;TriTree *t;strcpy(fname,familyname); /* 以家族名為文本文件名存儲*/strcat(fname,".txt");fp=fopen(fname,"r"); /* 以讀取方式打開文件*/ if(fp=NULL) /* 文件不存在*/printf("%s 的家族關(guān)系不存在!n",familyname);return NULL;elsech=fgetc(fp)

20、; /* 按字符讀取文件*/while(ch!=EOF) /* 讀到文件尾結(jié)束*/if(ch!='n') /* ch不為一個結(jié)點信息的結(jié)尾*/familyij=ch; /* 將文件信息存儲到family數(shù)組中*/j+; elsefamilyij='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("

21、;家族關(guān)系已成功打開!n");return t;2.4在家族關(guān)系中查找一個成員是否存在用遞歸算法實現(xiàn)。如果樹空,返回NULL。如果根節(jié)點就是要查找的成員,返回根節(jié)點;否則,遞歸查找它的左右子樹。/* 查找一個成員是否存在*/TriTree *Search(TriTree *t,DataType str) TriTree *temp;if(t=NULL) /* 如果樹空則返回NULL */return NULL;else if(strcmp(t->data,str)=0) /* 如果找到返回該成員指針*/return t; else /* 如果沒找到遍歷左右子樹進行查找*/tem

22、p=Search(t->lchild,str); /* 遞歸查找*/if(temp) /* 結(jié)點不空則查找*/return(Search(t->lchild,str);elsereturn(Search(t->rchild,str);2.5 向家族中添加一個新成員基本思想:添加的新成員要根據(jù)其雙親確定其在家族中的位置。首先判斷該雙親是否在此家族關(guān)系中,若存在則查找其雙親,將新結(jié)點插入其雙親的最后一個孩子之后;若沒有孩子,則直接作為左孩子插入。以寫入的方式打開文件,如果成功打開,則更新family數(shù)組中的信息,并查找新成員的雙親所在位置和其對應(yīng)的“”個數(shù),如果“”個數(shù)小于雙親位

23、置,則添加“”實質(zhì)相等,新成員不插入到最后“”之前。最后將family數(shù)組中信息寫入文件保存,關(guān)閉文件。/* 添加一個新成員*/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ù)輸入

24、*/gets(par);tpar=Search(t,par); /* 查找雙親結(jié)點是否存在*/if(!tpar)printf("%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

25、->lchild; /* 遍歷當(dāng)前成員左孩子的右子樹*/while(tpar->rchild) /* 當(dāng)前結(jié)點右孩子存在*/tpar=tpar->rchild; /* 繼續(xù)遍歷右孩子*/tpar->rchild=temp; /* 將新結(jié)點添加到所有孩子之后*/ else /* 沒有孩子則直接添加*/tpar->lchild=temp;fp=fopen(fname,"w"); /* 以寫入方式打開文件*/if(fp)while(strcmp(par,familyi)!=0&&familyi0!='#')if(fam

26、ilyi0!='') /* 查找雙親在數(shù)組中位置*/parpos+; /* parpos計數(shù)*/i+; /* family數(shù)組行下標(biāo)后移*/i=0; /* family數(shù)組行下標(biāo)歸*/while(familyi0!='#')if(familyi0='') /* 查找“”的個數(shù),第一個不計*/count+; /* count累加個數(shù)*/if(count=parpos) /* 說明此“”與其前一個“”之前為par的孩子*/curpos=i; /* curpos計當(dāng)前位置*/i+; /* family數(shù)組行下標(biāo)后移*/if(count<parpo

27、s) /* “”數(shù)小于parpos數(shù)*/num=parpos-count; /* 添加“”個數(shù)為num */for(j=i;j<=i+num;j+) /* 從數(shù)組末尾添加“”*/strcpy(familyj,"0"); strcpy(familyi+num+1,"#0");/* “#”移到數(shù)組末尾*/ strcpy(familyi+num-1,chi); /* 在最后一個“”前添加新成員*/ end=1; /* end為時標(biāo)記已添加*/ elsefor(j=i;j>=curpos;j-) /* 當(dāng)前位置到數(shù)組最后的全部信息后移一行*/strc

28、py(familyj+1,familyj);strcpy(familycurpos,chi); /* 將新結(jié)點存儲到“”的前一行*/if(end=1) /* 若end為,則數(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("添加新成員失?。");2.6 家族成員關(guān)系的相關(guān)查詢

29、 2.6.1 查找一個家族的鼻祖判斷輸入的姓名是否在該家族中存在,如果存在,則返回該家族的根節(jié)點信息。/* 查找一個家族的祖先*/void Ancesstor(TriTree *t) /* 返回樹的根結(jié)點信息*/printf("該家族的祖先為%sn",t->data);2.6.2 查找一個成員的所有祖先路徑查找一個成員的所有祖先路徑,需要從它的雙親一直向上查找到根結(jié)點?;舅枷耄簩εc結(jié)點t,先判斷它是否是根結(jié)點(根節(jié)點的雙親是NULL),如果是根結(jié)點,直接輸出它本身;如果不是,查找它的雙親指針指向的結(jié)點,將雙親信息輸出。繼續(xù)查找,直到找到根結(jié)點。/* 查找一個成員的所

30、有祖先*/void AncesstorPath(TriTree *t)if(t->parent=NULL) /* 若該成員為祖先,則直接輸出*/printf("%s 無祖先!n",t->data);else /* 否則繼續(xù)查找祖先*/printf("%s 所有祖先路徑:%s",t->data,t->data);while(t->parent!=NULL)/* 若當(dāng)前成員的雙親不是祖先,則繼續(xù)查找*/printf(" -> %s",t->parent->data);/* 訪問當(dāng)前成員的雙親

31、*/t=t->parent; /* 繼續(xù)循環(huán)查找*/printf("n");2.6.3 查找一個成員的雙親基本思想:先判斷結(jié)點t是否是根結(jié)點,過不是根結(jié)點,直接輸出該結(jié)點雙親指針的結(jié)點信息;若是根結(jié)點,輸出提示信息,結(jié)點無雙親。/* 查找一個成員的雙親*/void Parent(TriTree *t)if(t->parent!=NULL) /* 若該成員為祖先,則無雙親*/printf("%s 的雙親為%sn",t->data,t->parent->data);elseprintf("%s 無雙親!n",

32、t->data);2.6.4 確定一個成員是第幾代確定一個成員是第幾代,只要知道從它本身到根結(jié)點包括的祖先個數(shù)就可。因而對于跟結(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->par

33、ent;printf("%s 是第%d 代!n",str,count);2.6.5 查找一個成員的兄弟 一個成員的為其雙親除了該成員以外的所有孩子。 基本思想:對于結(jié)點t,先判斷它是否是跟結(jié)點,若是根結(jié)點,則無兄弟;若不是根結(jié)點,則找到結(jié)點t的雙親。接著判斷雙親的左孩子和左孩子的兄弟是否都存在(若只有左孩子,左孩子就是要查找的這個成員),如果都不存在,則無兄弟;如果都存在,對雙親的左孩子操作。若左孩子不是要查找的這個成員,則將結(jié)點信息輸出。接下來查找左孩子的右兄弟,判斷當(dāng)前結(jié)點是否是要查找的這個成員,若不是,則將結(jié)點信息輸出,繼續(xù)查找當(dāng)前結(jié)點的右兄弟,直到NULL為止。/*

34、 查找一個成員的兄弟*/void Brothers(TriTree *t,DataType str) /* 查找兄弟*/ if(t->parent!=NULL) /* 若該結(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(str

35、cmp(t->data,str)!=0) /* 遍歷右子樹,選擇輸出*/printf("%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的

36、雙親,那么爺爺還有其他孩子。現(xiàn)對爺爺?shù)淖蠛⒆拥淖蠛⒆釉L問,如果不是結(jié)點t就輸出。同樣,對爺爺左孩子的左孩子的右孩子、右孩子的右孩子一直訪問下去,直到無右孩子為止。如果爺爺還有其他孩子,那么就對爺爺?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-&g

37、t;parent->lchild;/* 當(dāng)前結(jié)點等于其祖先的第一個孩子*/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

38、->data);printf("%s ",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、果沒有,輸出沒有孩子;如果有左孩子,輸出左孩子的信息,然后判斷左孩子的右孩子是否為空,若不為空(存在右孩子),輸出左孩子的右孩子的信息,接著循環(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-&g

40、t;data);/* 訪問當(dāng)前成員*/t=t->rchild; printf("n");elseprintf("%s 無孩子!n",t->data);/* 中序遍歷一棵樹*/void InOrder(TriTree *t) if(t) /* 二叉樹存在*/InOrder(t->lchild); /* 中序遍歷左子樹*/printf("%s ",t->data);/* 訪問成員*/InOrder(t->rchild); /* 中序遍歷右子樹*/2.6.8 查找一個成員的子孫后代 一個成員的子孫后代就是其左子

41、樹上的所有結(jié)點,所以對其左子樹進行中序遍歷即可。/* 查找一個成員的子孫后代*/ void Descendants(TriTree *t) /* 遍歷左孩子*/ if(t->lchild) /* 當(dāng)前結(jié)點存在左孩子*/printf("%s 的所有子孫后代有:",t->data);InOrder(t->lchild); /* 中序遍歷當(dāng)前結(jié)點的左右子樹*/printf("n");elseprintf("%s 無后代!n",t->data);2.7 各軟件之間的調(diào)用方式該軟件各個模塊的調(diào)用主要是通過聲明函數(shù),和定義

42、函數(shù) 再通過主函數(shù)調(diào)用實現(xiàn)的。主函數(shù): /* 主控函數(shù)*/int main(int 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ù),如parent(C)n");printf("t 1.新建一個家庭關(guān)系: Create(familyname) 參數(shù)為字

43、符串n");printf("t 2.打開一個家庭關(guān)系: Open(familyname) 參數(shù)為字符串n");printf("t 3.添加新成員的信息: Append() 無參數(shù)n");printf("t 4.查找一個成員的祖先: Ancesstor(name) 參數(shù)為字符串n");printf("t 5.查找一個成員的祖先路徑:AncesstorPath(name) 參數(shù)為字符串n");printf("t 6.確定一個成員是第幾代: Generation(name) 參數(shù)為字符串n"

44、);printf("t 7.查找一個成員的雙親: Parent(name) 參數(shù)為字符串n");printf("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(

45、"t12.退出系統(tǒng): Exit() 無參數(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(inputi='(') /* 左括號之前為函數(shù)名*/pos=i; /* pos標(biāo)記左括號位置*/tag1=1; /* 標(biāo)記是否匹配到左括號*/if(inputi+1=')') /* 若下一個字符不為右括號*/tag2=1; /* 標(biāo)記為*/if(tag1=1&&tag2!=1)

46、 /* 左括號和右括號之前為參數(shù)*/strj=tolower(inputi+1);/* 將參數(shù)存放到str數(shù)組*/j+; /* 并轉(zhuǎn)化為小寫字母*/inputi=tolower(inputi); /* 將函數(shù)名轉(zhuǎn)化為小寫字母*/if(!tag1)/* 若沒匹配到左括號,說明只有函數(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

47、(input,"open0")=0) flag=2;else if(strcmp(input,"append0")=0)flag=3;else if(strcmp(input,"ancesstor0")=0)flag=4;else if(strcmp(input,"ancesstorpath0")=0)flag=5;else if(strcmp(input,"parent0")=0)flag=6;else if(strcmp(input,"generation0")=0)flag=7;else if(strcmp(input,"brothers0")=0)flag=8;else if(strcmp(input,"consin0")=0)flag=9;else if(strcmp(input,"children0")=0)flag=10;else if(strcmp(input,"descendants0")=0)flag=11;else if(strcmp(input,"exit0")=0)fla

溫馨提示

  • 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)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論