數據結構課程設計(家族關系查詢系統(tǒng))_第1頁
已閱讀1頁,還剩27頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、<p><b>  1 課程設計介紹 </b></p><p>  1.1課程設計項目簡介 </p><p>  家譜是一種以表譜形式,記載一個以血緣關系為主體的家族世系繁衍和重要人物事跡的特殊圖書載體。家譜是中國特有的文化遺產,是中華民族的三大文獻之一,屬珍貴的人文資料,對于歷史學,民俗學,人口學,社會學和經濟學的深入研究,均有不可替代的重要功能。本項目對

2、家譜管理進行簡單的模擬,以實現查看祖先和子孫個人信息 、插入家族成員等功能。 </p><p><b>  1.2課設題目分析</b></p><p>  本程序的實質是完成對家譜成員信息的建立、查找、插入等功能??梢允紫榷x家族成員的數據結構,然后將每個功能寫成一個函數來完成對數據的操作,最后完成主函數以驗證各個函數功能并得出運行結果。</p><

3、;p>  本程序包含以下幾個模塊</p><p>  建立家族關系樹。此模塊將構建一個家族關系,對數據初始化,構造關系樹并錄入數據一遍后續(xù)程序使用。</p><p>  添加新成員。此模塊將添加一個新成員,實現對家族關系的修改。</p><p>  家族關系的查詢。此模塊將實現對家族不同關系的查詢</p><p>  主程序模塊。此模塊

4、實現整個程序的進入和進出,以及各種初始化處理。</p><p>  1.3課程題目原理與數據結構</p><p>  因為家族的成員之間存在一個對多個的層次結構關系,所以不能用線性表來表示和實現。家譜從形狀上看像一顆倒長的樹,所以用樹結構來表示比較合適。樹形結構是一類非常重要的非線性數據結構,直觀看來樹是以分支關系定義的層次結構。</p><p>  因此本課程設計

5、可以采用的數據結構有樹狀結構和隊列。樹狀結構采用三叉鏈表來實現,隊列采用鏈式隊列實現。</p><p>  1.4功能分析說明圖</p><p>  2 分析與實現 </p><p>  2.1 基本數據結構和棧隊的操作</p><p>  2.1.1 結點基本數據結構和鏈隊的定義</p><p>  /*家族關系

6、樹實現*/</p><p>  #include <string.h></p><p>  #include <malloc.h></p><p>  #include<limits.h></p><p>  #include<stdio.h></p><p>  #in

7、clude<stdlib.h></p><p>  #include<io.h></p><p>  #include<math.h></p><p>  #include<process.h></p><p>  #define TRUE 1</p><p>  #de

8、fine FALSE 0</p><p>  #define OK 1</p><p>  #define ERROR -1</p><p>  #define INFEASIBLE -1</p><p>  typedef char DataType;</p><p>  #define MAXNUM 20</

9、p><p>  typedef struct TriTNode/* 樹的三叉鏈表存儲結構*/</p><p><b>  { </b></p><p>  DataType data[MAXNUM];</p><p>  struct TriTNode *parent;/* 雙親*/</p><p>

10、  struct TriTNode *lchild;/* 左孩子*/</p><p>  struct TriTNode *rchild;/* 右孩子*/</p><p><b>  }TriTree;</b></p><p>  typedef struct Node/* 隊列的結點結構*/</p><p><b

11、>  { </b></p><p>  TriTree *info;</p><p>  struct Node *next;</p><p><b>  }Node;</b></p><p>  typedef struct/* 鏈接隊列類型定義*/</p><p><

12、;b>  {</b></p><p>  struct Node *front; /* 頭指針*/</p><p>  struct Node *rear; /* 尾指針*/</p><p>  }LinkQueue;</p><p>  DataType fname[MAXNUM],family[50]

13、[MAXNUM];/* 全局變量*/</p><p>  2.1.2 鏈隊的基本操作</p><p>  LinkQueue *LQueueCreateEmpty( )/* 建立一個空隊列*/</p><p><b>  { </b></p><p>  LinkQueue *plqu=(LinkQueue *)mal

14、loc(sizeof(LinkQueue));</p><p>  if (plqu!=NULL)</p><p>  plqu->front=plqu->rear=NULL;</p><p><b>  else</b></p><p><b>  {</b></p>&

15、lt;p>  printf("內存不足!\n");</p><p>  return NULL;</p><p><b>  }</b></p><p>  return plqu;</p><p><b>  }</b></p><p>  in

16、t LQueueIsEmpty(LinkQueue *plqu)/* 判斷鏈接表示隊列是否為空隊列*/ </p><p><b>  {</b></p><p>  return(plqu->front==NULL);</p><p><b>  }</b></p><p>  void LQ

17、ueueEnQueue(LinkQueue *plqu,TriTree *x)/* 進隊列*/</p><p><b>  { </b></p><p>  Node *p=(Node *)malloc(sizeof(Node));</p><p>  if(p==NULL)</p><p>  printf("

18、;內存分配失??!\n");</p><p><b>  else</b></p><p><b>  { </b></p><p>  p->info=x;</p><p>  p->next=NULL;</p><p>  if(plqu->fr

19、ont==NULL)/* 原來為空隊*/</p><p>  plqu->front=p;</p><p><b>  else</b></p><p>  plqu->rear->next=p;</p><p>  plqu->rear=p;</p><p><b&

20、gt;  }</b></p><p><b>  }</b></p><p>  int LQueueDeQueue(LinkQueue *plqu,TriTree *x)/* 出隊列*/</p><p><b>  { </b></p><p><b>  Node *p;&

21、lt;/b></p><p>  if(plqu->front==NULL)</p><p><b>  {</b></p><p>  printf("隊列空!\n");</p><p>  return ERROR;</p><p><b>  }&l

22、t;/b></p><p><b>  else</b></p><p><b>  { </b></p><p>  p=plqu->front;</p><p>  x=p->info;</p><p>  plqu->front=plqu->

23、;front->next;</p><p><b>  free(p);</b></p><p>  return OK;</p><p><b>  }</b></p><p><b>  }</b></p><p>  TriTree *LQu

24、eueGetFront(LinkQueue *plqu)/* 在非空隊列中求隊頭元素*/</p><p><b>  { </b></p><p>  return(plqu->front->info);</p><p><b>  }</b></p><p><b>  2.

25、2建立家族關系</b></p><p>  2.2.1 建立家族關系并存入文件 </p><p>  基本思想:首先輸入家族關系的名稱,以此名稱為文件名,建立文本文件接下來按層次輸入結點信息,輸入一個在文件中寫入一行同時將輸入的信息保存 </p><p>  到二位字符數組family中。字符數組family是全局變量,存儲

26、臨時信息 . 注意,輸入時每個結點信息占一行,一個結點有多個兄弟,以“@”作為兄弟結束標志,結點若無孩子,直接以“@”代替。依次輸入各節(jié)點信息,以“#” 作為結束標志。最后使用函數CreateTriTree建立家族關系樹.</p><p>  TriTree *Create(DataType familyname[MAXNUM])/* 建立家族關系并存入文件*/</p><p><b

27、>  {</b></p><p>  int i=0; /* i控制family數組下標*/</p><p>  DataType ch,str[MAXNUM]; /* ch存儲輸入的y或n,str存儲輸入的字符串*/</p><p>  TriTree *t;</p><p><

28、;b>  FILE *fp;</b></p><p>  strcpy(fname,familyname); /* 以家族名為文本文件名存儲*/</p><p>  strcat(fname,".txt");</p><p>  fp=fopen(fname,"r"); /* 以讀取方式打開文件

29、*/ </p><p>  if(fp) /* 文件已存在*/</p><p><b>  {</b></p><p>  fclose(fp);</p><p>  printf("%s 的家族關系已存在!重新建立請按“Y”,直接打開請按“N”\n",fami

30、lyname);</p><p>  ch=getchar();</p><p>  getchar(); /* 接收回車*/</p><p>  if(ch=='N'||ch=='n')</p><p><b>  {</b></p><p&g

31、t;  t=Open(familyname);/* 直接打開*/</p><p><b>  return t;</b></p><p><b>  }</b></p><p><b>  }</b></p><p>  if(!fp||ch=='Y'||ch=

32、='y') /* 重新建立,執(zhí)行以下操作*/</p><p><b>  {</b></p><p>  fp=fopen(fname,"w"); /* 以寫入方式打開文件,不存在則新建*/</p><p>  printf("請按層次輸入結點,每個結點信息占一行\(zhòng)n")

33、;</p><p>  printf("兄弟輸入結束以“@”為標志,結束標志為“#”\n. ");</p><p>  gets(str);</p><p>  fputs(str,fp);</p><p>  fputc('\n',fp);</p><p>  strcpy(fam

34、ily[i],str); /* 將成員信息存儲到字符數組中*/</p><p>  i++; /* family數組下標后移*/</p><p>  while(str[0]!='#') </p><p><b>  {</b></p><p>  print

35、f(". "); /* 以點提示符提示繼續(xù)輸入*/</p><p>  gets(str);</p><p>  fputs(str,fp); /* 寫到文件中,每個信息占一行*/</p><p>  fputc('\n',fp);</p><p>  strcpy(family[i],s

36、tr);/* 將成員信息存儲到字符數組中*/</p><p>  i++; /* family數組下標后移*/</p><p><b>  }</b></p><p>  fclose(fp); /* 關閉文件*/</p><p>  t=TriTreeCre

37、ate(); /* 根據family數組信息創(chuàng)建三叉樹*/</p><p>  printf("家族關系已成功建立!\n");</p><p>  return t; /* 返回樹*/</p><p><b>  }</b></p><p><b>  }&

38、lt;/b></p><p>  2.2.2建立家族關系樹</p><p>  基本思想:采用指針數組作為指針,保存輸入的結點地址。隊列的尾指針指向當前結點。頭指針指向當前結點的雙親結點。輸入的結點信息已存儲在字符數組family中。</p><p>  將信息復制到字符串數組“ch”中 ,如果"ch"不是“@”,則建立一個新結點。若新結點

39、是第一個結點,則它是根結點,將其入隊,指針tree指向這個根節(jié)點;如果不是根結點,則將當前結點鏈接到雙親結點上,即當前結點的雙親指針就是隊頭元素,然后將當前結點入隊列。接著判斷flag的值,如果flag=0,表示當前結點沒有左孩子,那么當前結點就是雙親的左孩子。否則,當前結點就是雙親的右孩子。用指針root指向剛剛入隊的結點。繼續(xù)復制數組family的下個元素。如果“ch” 是@。則flag=0(因為“@”后面的第一個孩子為左孩子),同

40、時判斷“@”是否是第一次出現,如果是第一次,則令標志star=1;如果不是第一次出現。則出隊列,root指向隊頭元素(實際上root總是指向雙親結點)。繼續(xù)復制family的下一個元素。知道遇到“#”結束。函數返回指針tree。</p><p>  /* 建立家族關系樹*/</p><p>  TriTree *TriTreeCreate()</p><p><

41、;b>  {</b></p><p>  TriTree *t,*x=NULL,*tree,*root=NULL;</p><p>  LinkQueue *q=LQueueCreateEmpty();/* 建立一個空的隊列,存儲指向樹的指針*/</p><p>  int i=0,flag=0,start=0;</p><p&

42、gt;  DataType str[MAXNUM]; /* 存放family數組中信息*/</p><p>  strcpy(str,family[i]); /* 復制*/</p><p>  i++; /* family數組下標后移*/</p><p>  while(str[0

43、]!='#') /* 沒遇到結束標志繼續(xù)循環(huán)*/</p><p><b>  {</b></p><p>  while(str[0]!='@') /* 沒遇到兄弟輸入結束標志繼續(xù)*/</p><p><b>  {</b></p><p>

44、;  if(root==NULL) /* 空樹*/</p><p><b>  {</b></p><p>  root=(TriTree *)malloc(sizeof(TriTree));/* 申請空間*/</p><p>  strcpy(root->data,str);</p><p>

45、  root->parent=NULL;</p><p>  root->lchild=NULL;</p><p>  root->rchild=NULL;</p><p>  LQueueEnQueue(q,root); /* 將root存入隊列*/</p><p>  tree=r

46、oot;</p><p><b>  }</b></p><p>  else /* 不為空樹*/</p><p><b>  {</b></p><p>  t=(TriTree *)malloc(sizeof(TriTree)); /*

47、申請空間*/</p><p>  strcpy(t->data,str);</p><p>  t->lchild=NULL;</p><p>  t->rchild=NULL;</p><p>  t->parent=LQueueGetFront(q); /* 當前結點的雙親為隊頭元素*/</p

48、><p>  LQueueEnQueue(q,t); /* 入隊*/</p><p>  if(!flag) /* flag為,當前結點沒有左孩子*/</p><p>  root->lchild=t;</p><p>  else /* flag為,當前結點已有左孩子*/</p>

49、<p>  root->rchild=t;</p><p>  root=t; /* root指向新的結點t */</p><p><b>  }</b></p><p>  flag=1; /* 標記當前結點已有左孩子*/</p><p>  st

50、rcpy(str,family[i]); </p><p><b>  i++;</b></p><p><b>  }</b></p><p>  if(start!=0) /* 標記不是第一次出現“@”*/</p><p><b>  {</b

51、></p><p>  LQueueDeQueue(q,x); /* 出隊*/</p><p>  if(q->front!=NULL)</p><p>  root=LQueueGetFront(q);/* root為隊頭元素*/</p><p><b>  }</b></p

52、><p>  start=1; /* 標記已出現過“@”*/</p><p>  flag=0; /* “@”后面的結點一定為左孩子*/</p><p>  strcpy(str,family[i]);</p><p><b>  i++;</b><

53、/p><p><b>  }</b></p><p>  return tree; /* 返回樹*/</p><p><b>  }</b></p><p>  2.3打開一個家族關系 </p><p>  首先輸入家族關系名,以

54、家族名為文件名打開文件,如果家族關系不存在,返回空;如果存在,文件打開,讀取文件。將文件的每行信息依次存儲在數組family【】中。</p><p>  /* 打開一個家族關系*/</p><p>  TriTree *Open(DataType familyname[MAXNUM])</p><p><b>  {</b></p>

55、<p>  int i=0,j=0;</p><p>  DataType ch;</p><p><b>  FILE *fp;</b></p><p>  TriTree *t;</p><p>  strcpy(fname,familyname); /* 以家族名為文本文件名存儲*/</p&g

56、t;<p>  strcat(fname,".txt");</p><p>  fp=fopen(fname,"r"); /* 以讀取方式打開文件*/ </p><p>  if(fp==NULL) /* 文件不存在*/</p><p><b>

57、;  {</b></p><p>  printf("%s 的家族關系不存在!\n",familyname);</p><p>  return NULL;</p><p><b>  }</b></p><p><b>  else</b></p>&

58、lt;p><b>  {</b></p><p>  ch=fgetc(fp); /* 按字符讀取文件*/</p><p>  while(ch!=EOF) /* 讀到文件尾結束*/</p><p><b>  {</b></p><p>  

59、if(ch!='\n') /* ch不為一個結點信息的結尾*/</p><p><b>  {</b></p><p>  family[i][j]=ch; /* 將文件信息存儲到family數組中*/</p><p>  j++; </p><p><

60、;b>  }</b></p><p><b>  else</b></p><p><b>  {</b></p><p>  family[i][j]='\0'; /* 字符串結束標志*/</p><p>  i++; /* fa

61、mily數組行下標后移*/</p><p>  j=0; /* family數組列下標歸零*/</p><p><b>  }</b></p><p>  ch=fgetc(fp); /* 繼續(xù)讀取文件信息*/</p><p><b>  }</b><

62、;/p><p>  fclose(fp); /* 關閉文件*/</p><p>  t=TriTreeCreate(family); /* 調用函數建立三叉鏈表*/</p><p>  printf("家族關系已成功打開!\n");</p><p><b>  return t;<

63、/b></p><p><b>  }</b></p><p><b>  }</b></p><p>  2.4在家族關系中查找一個成員是否存在</p><p>  用遞歸算法實現。如果樹空,返回NULL。如果根節(jié)點就是要查找的成員,返回根節(jié)點;否則,遞歸查找它的左右子樹。</p>

64、;<p>  /* 查找一個成員是否存在*/</p><p>  TriTree *Search(TriTree *t,DataType str[]) </p><p><b>  {</b></p><p>  TriTree *temp;</p><p>  if(t==NULL)

65、 /* 如果樹空則返回NULL */</p><p>  return NULL;</p><p>  else if(strcmp(t->data,str)==0) /* 如果找到返回該成員指針*/</p><p>  return t; </p><p>  else

66、 /* 如果沒找到遍歷左右子樹進行查找*/</p><p><b>  {</b></p><p>  temp=Search(t->lchild,str); /* 遞歸查找*/</p><p>  if(temp) /* 結點不空則查找*/</p><p>  retu

67、rn(Search(t->lchild,str));</p><p><b>  else</b></p><p>  return(Search(t->rchild,str));</p><p><b>  }</b></p><p><b>  }</b><

68、;/p><p>  2.5 向家族中添加一個新成員</p><p>  基本思想:添加的新成員要根據其雙親確定其在家族中的位置。首先判斷該雙親是否在此家族關系中,若存在則查找其雙親,將新結點插入其雙親的最后一個孩子之后;若沒有孩子,則直接作為左孩子插入。以寫入的方式打開文件,如果成功打開,則更新family數組中的信息,并查找新成員的雙親所在位置和其對應的“@”個數,如果“@”個數小于雙親位置

69、,則添加“@”實質相等,新成員不插入到最后“@”之前。最后將family數組中信息寫入文件保存,關閉文件。</p><p>  /* 添加一個新成員*/</p><p>  void Append(TriTree *t)</p><p><b>  {</b></p><p>  int i=0,j,parpos=1,c

70、urpos,num,end=0,count=-1;</p><p>  DataType chi[MAXNUM],par[MAXNUM];/* 存儲輸入的孩子和其雙親結點*/</p><p>  TriTree *tpar,*temp;</p><p><b>  FILE *fp;</b></p><p>  prin

71、tf("請輸入要添加的成員和其父親,以回車分隔!\n. ");</p><p>  gets(chi);</p><p>  printf(". "); /* 以點提示符提示繼續(xù)輸入*/</p><p>  gets(par);</p><p>  tpar=Search(t,par);

72、 /* 查找雙親結點是否存在*/</p><p><b>  if(!tpar)</b></p><p>  printf("%s 該成員不存在!\n");</p><p>  else /* 存在則添加其孩子*/</p><p><b>  {</b&

73、gt;</p><p>  temp=(TriTree *)malloc(sizeof(TriTree));/* 申請空間*/</p><p>  temp->parent=tpar; </p><p>  strcpy(temp->data,chi);</p><p>  temp->lchild

74、=NULL; /* 新結點左右孩子置空*/</p><p>  temp->rchild=NULL;</p><p>  if(tpar->lchild) /* 成員存在左孩子*/</p><p><b>  {</b></p><p>  tpar=tpar-

75、>lchild; /* 遍歷當前成員左孩子的右子樹*/</p><p>  while(tpar->rchild) /* 當前結點右孩子存在*/</p><p>  tpar=tpar->rchild; /* 繼續(xù)遍歷右孩子*/</p><p>  tpar->rchild=temp; /*

76、 將新結點添加到所有孩子之后*/</p><p>  } </p><p>  else /* 沒有孩子則直接添加*/</p><p>  tpar->lchild=temp;</p><p>  fp=fopen(fna

77、me,"w"); /* 以寫入方式打開文件*/</p><p><b>  if(fp)</b></p><p><b>  {</b></p><p>  while(strcmp(par,family[i])!=0&&family[i][0]!='#'

78、)</p><p><b>  {</b></p><p>  if(family[i][0]!='@') /* 查找雙親在數組中位置*/</p><p>  parpos++; /* parpos計數*/</p><p>  i++;

79、 /* family數組行下標后移*/</p><p><b>  }</b></p><p>  i=0; /* family數組行下標歸*/</p><p>  while(family[i][0]!='#')</p><p><b>  {&l

80、t;/b></p><p>  if(family[i][0]=='@') /* 查找“@”的個數,第一個不計*/</p><p>  count++; /* count累加個數*/</p><p>  if(count==parpos) /* 說明此“@”與其前一個“@”之前

81、為par的孩子*/</p><p>  curpos=i; /* curpos計當前位置*/</p><p>  i++; /* family數組行下標后移*/</p><p><b>  }</b></p><p>  if(count<parpos)

82、 /* “@”數小于parpos數*/</p><p><b>  {</b></p><p>  num=parpos-count; /* 添加“@”個數為num */</p><p>  for(j=i;j<=i+num;j++) /* 從數組末尾添加“@”*/</p><p>  strcpy

83、(family[j],"@\0"); </p><p>  strcpy(family[i+num+1],"#\0");/* “#”移到數組末尾*/ </p><p>  strcpy(family[i+num-1],chi); /* 在最后一個“@”前添加新成員*/ </p><p>  end=1;

84、 /* end為時標記已添加*/ </p><p><b>  }</b></p><p><b>  else</b></p><p><b>  {</b></p><p>  for(j=i;j>=curpos;j--) /* 當前位置

85、到數組最后的全部信息后移一行*/</p><p>  strcpy(family[j+1],family[j]);</p><p>  strcpy(family[curpos],chi); /* 將新結點存儲到“@”的前一行*/</p><p><b>  }</b></p><p>  if(end==1) /*

86、 若end為,則數組末尾下標后移num位*/ </p><p><b>  i=i+num;</b></p><p>  for(j=0;j<=i+1;j++) /* 將數組所有信息寫入文件*/</p><p><b>  {</b></p><p>  fputs(family[j],f

87、p);</p><p>  fputc('\n',fp); /* 一個信息存一行*/</p><p><b>  }</b></p><p>  fclose(fp); /* 關閉文件*/</p><p>  printf("添

88、加新成員成功!\n");</p><p><b>  }</b></p><p><b>  else</b></p><p>  printf("添加新成員失?。n");</p><p><b>  }</b></p><p

89、><b>  }</b></p><p>  2.6 家族成員關系的相關查詢</p><p>  2.6.1 查找一個家族的鼻祖</p><p>  判斷輸入的姓名是否在該家族中存在,如果存在,則返回該家族的根節(jié)點信息。</p><p>  /* 查找一個家族的祖先*/</p><p>  

90、void Ancesstor(TriTree *t) /* 返回樹的根結點信息*/</p><p><b>  {</b></p><p>  printf("該家族的祖先為%s\n",t->data);</p><p><b>  }</b></p><

91、p>  2.6.2 查找一個成員的所有祖先路徑</p><p>  查找一個成員的所有祖先路徑,需要從它的雙親一直向上查找到根結點。</p><p>  基本思想:對與結點t,先判斷它是否是根結點(根節(jié)點的雙親是NULL),如果是根結點,直接輸出它本身;如果不是,查找它的雙親指針指向的結點,將雙親信息輸出。繼續(xù)查找,直到找到根結點。</p><p>  /*

92、查找一個成員的所有祖先*/</p><p>  void AncesstorPath(TriTree *t)</p><p><b>  {</b></p><p>  if(t->parent==NULL) /* 若該成員為祖先,則直接輸出*/</p><p>  printf("%s 無祖先!

93、\n",t->data);</p><p>  else /* 否則繼續(xù)查找祖先*/</p><p><b>  {</b></p><p>  printf("%s 所有祖先路徑:%s",t->data,t->data);</p>

94、;<p>  while(t->parent!=NULL)/* 若當前成員的雙親不是祖先,則繼續(xù)查找*/</p><p><b>  {</b></p><p>  printf(" --> %s",t->parent->data);/* 訪問當前成員的雙親*/</p><p>  

95、t=t->parent; /* 繼續(xù)循環(huán)查找*/</p><p><b>  }</b></p><p>  printf("\n");</p><p><b>  }</b></p><p><b>  }</b>

96、</p><p>  2.6.3 查找一個成員的雙親</p><p>  基本思想:先判斷結點t是否是根結點,過不是根結點,直接輸出該結點雙親指針的結點信息;若是根結點,輸出提示信息,結點無雙親。</p><p>  /* 查找一個成員的雙親*/</p><p>  void Parent(TriTree *t)</p><

97、;p><b>  {</b></p><p>  if(t->parent!=NULL) /* 若該成員為祖先,則無雙親*/</p><p>  printf("%s 的雙親為%s\n",t->data,t->parent->data);</p><p><b>  else<

98、;/b></p><p>  printf("%s 無雙親!\n",t->data);</p><p><b>  }</b></p><p>  2.6.4 確定一個成員是第幾代</p><p>  確定一個成員是第幾代,只要知道從它本身到根結點包括的祖先個數就可。因而對于跟結點t,從它

99、本身開始一直向上查找到根結點,查找的過程中用變量count(初值為1)計數,最后輸出 count。</p><p>  /* 確定一個成員是第幾代*/</p><p>  void Generation(TriTree *t)</p><p><b>  {</b></p><p>  int count=1;

100、 /* 計數*/</p><p>  DataType str[MAXNUM];</p><p>  strcpy(str,t->data); /* 存儲當前信息*/</p><p>  while(t->parent!=NULL)/* 查找其雙親*/</p><p><b>  {</b><

101、/p><p>  count++; /* 累加計數*/</p><p>  t=t->parent;</p><p><b>  }</b></p><p>  printf("%s 是第%d 代!\n",str,count);</p><p><b&

102、gt;  }</b></p><p>  2.6.5 查找一個成員的兄弟</p><p>  一個成員的為其雙親除了該成員以外的所有孩子。</p><p>  基本思想:對于結點t,先判斷它是否是跟結點,若是根結點,則無兄弟;若不是根結點,則找到結點t的雙親。接著判斷雙親的左孩子和左孩子的兄弟是否都存在(若只有左孩子,左孩子就是要查找的這個成員),如果都

103、不存在,則無兄弟;如果都存在,對雙親的左孩子操作。若左孩子不是要查找的這個成員,則將結點信息輸出。接下來查找左孩子的右兄弟,判斷當前結點是否是要查找的這個成員,若不是,則將結點信息輸出,繼續(xù)查找當前結點的右兄弟,直到NULL為止。</p><p>  /* 查找一個成員的兄弟*/</p><p>  void Brothers(TriTree *t,DataType str[]) /

104、* 查找兄弟*/</p><p><b>  { </b></p><p>  if(t->parent!=NULL) /* 若該結點是祖先,則無兄弟*/</p><p><b>  {</b></p><p>  t=t->parent;

105、 /* 該結點的兄弟即為其雙親除該成員以外的所有孩子*/</p><p>  if(t->lchild&&t->lchild->rchild) /* 當前結點的左孩子及其右孩子都存在*/</p><p><b>  {</b></p><p>  printf("%s 的所有兄弟有:

106、",str);</p><p>  t=t->lchild; </p><p>  while(t) /* 遍歷當前成員左孩子的右子樹*/</p><p><b>  { </b></p><p>  if(strcmp(t->data,str)!=

107、0) /* 遍歷右子樹,選擇輸出*/</p><p>  printf("%s ",t->data); /* 訪問當前結點*/</p><p>  t=t->rchild;</p><p><b>  }</b></p><p>  printf("\n");<

108、;/p><p><b>  }</b></p><p><b>  else</b></p><p>  printf("%s 無兄弟!\n",str);</p><p><b>  }</b></p><p><b>  el

109、se</b></p><p>  printf("%s 無兄弟!\n",str);</p><p><b>  }</b></p><p>  2.6.6 查找一個成員的堂兄弟</p><p>  一個成員的堂兄弟為其雙親的雙親結點的所有孩子的孩子(該成員除外).</p>

110、<p>  基本思想:如果結點t的雙親和雙親的雙親(爺爺)都存在,首先考慮爺爺的左孩子。如果爺爺的左孩子不是結點t的雙親,那么爺爺還有其他孩子?,F對爺爺的左孩子的左孩子訪問,如果不是結點t就輸出。同樣,對爺爺左孩子的左孩子的右孩子、右孩子的右孩子一直訪問下去,直到無右孩子為止。如果爺爺還有其他孩子,那么就對爺爺的左孩子的右孩子、爺爺的左孩子的右孩子的右孩子------即對爺爺的其他孩子做相同的處理。</p>&l

111、t;p>  /* 查找一個成員的堂兄弟*/</p><p>  void Consin(TriTree *t)</p><p><b>  {</b></p><p>  int flag=0;</p><p>  TriTree *ch=t;</p><p>  TriTree *temp

112、;</p><p>  if(t->parent&&t->parent->parent)/* 當前結點的雙親及其雙親都存在*/</p><p><b>  {</b></p><p>  t=t->parent->parent->lchild;/* 當前結點等于其祖先的第一個孩子*/</

113、p><p>  while(t) /* 存在則繼續(xù)查找*/ </p><p><b>  { </b></p><p>  if(strcmp(t->data,ch->parent->data)!=0)/* 不是同一結點*/</p><

114、;p><b>  {</b></p><p>  if(t->lchild) /* 當前結點存在左孩子*/</p><p><b>  {</b></p><p>  temp=t->lchild;</p><p>  while(temp)

115、 /* 遍歷當前結點左孩子的右子樹*/</p><p><b>  { </b></p><p>  if(strcmp(temp->data,ch->data)!=0)</p><p><b>  {</b></p><p>  if(!flag)

116、 /* 第一次輸入時先輸出下句*/</p><p>  printf("%s 的所有堂兄弟有:",ch->data);</p><p>  printf("%s ",temp->data);/* 訪問當前成員*/</p><p><b>  flag=1;</b></p>&

117、lt;p><b>  }</b></p><p>  temp=temp->rchild; /* 繼續(xù)遍歷右孩子*/</p><p><b>  }</b></p><p><b>  }</b></p><p><b>  }<

118、;/b></p><p>  t=t->rchild; /* 繼續(xù)遍歷右孩子*/</p><p><b>  }</b></p><p>  printf("\n");</p><p><b>  }</b></p>&

119、lt;p>  if(!flag) /* 標志沒有輸出結點*/</p><p>  printf("%s 無堂兄弟!\n",ch->data);</p><p><b>  }</b></p><p>  2.6.7 查找一個成員的所有孩子</p><p>  一個成員的所有孩

120、子包括左孩子和左孩子的右孩子、左孩子的右孩子的右孩子----直到右孩子為空為止。</p><p>  基本思想:首先判斷結點t是否有左孩子,如果沒有,輸出沒有孩子;如果有左孩子,輸出左孩子的信息,然后判斷左孩子的右孩子是否為空,若不為空(存在右孩子),輸出左孩子的右孩子的信息,接著循環(huán)判斷結點是否有右孩子,有就輸出,直到右孩子為空。</p><p>  /* 查找一個成員的所有孩子*/&l

121、t;/p><p>  void Children(TriTree *t) /* 遍歷左孩子*/</p><p><b>  { </b></p><p>  if(t->lchild) /* 當前結點存在左孩子*/</p><p><b>  {</b&g

122、t;</p><p>  printf("%s 的所有孩子有:",t->data);</p><p>  t=t->lchild; /* 遍歷當前成員左孩子的右子樹*/</p><p>  while(t) /* 不空*/ </p><p><

123、b>  { </b></p><p>  printf("%s ",t->data);/* 訪問當前成員*/</p><p>  t=t->rchild; </p><p><b>  }</b></p><p>  printf("\n");

124、</p><p><b>  }</b></p><p><b>  else</b></p><p>  printf("%s 無孩子!\n",t->data);</p><p><b>  }</b></p><p>  /

125、* 中序遍歷一棵樹*/</p><p>  void InOrder(TriTree *t) </p><p><b>  {</b></p><p>  if(t) /* 二叉樹存在*/</p><p><b>  {</b></p&g

126、t;<p>  InOrder(t->lchild); /* 中序遍歷左子樹*/</p><p>  printf("%s ",t->data);/* 訪問成員*/</p><p>  InOrder(t->rchild); /* 中序遍歷右子樹*/</p><p><b>  }</

127、b></p><p><b>  }</b></p><p>  2.6.8 查找一個成員的子孫后代</p><p>  一個成員的子孫后代就是其左子樹上的所有結點,所以對其左子樹進行中序遍歷即可。</p><p>  /* 查找一個成員的子孫后代*/ </p><p>  void De

128、scendants(TriTree *t) /* 遍歷左孩子*/</p><p><b>  { </b></p><p>  if(t->lchild) /* 當前結點存在左孩子*/</p><p><b>  {</b></p><p>  printf(&q

129、uot;%s 的所有子孫后代有:",t->data);</p><p>  InOrder(t->lchild); /* 中序遍歷當前結點的左右子樹*/</p><p>  printf("\n");</p><p><b>  }</b></p><p><b>

130、  else</b></p><p>  printf("%s 無后代!\n",t->data);</p><p><b>  }</b></p><p>  2.7 各軟件之間的調用方式</p><p>  該軟件各個模塊的調用主要是通過聲明函數,和定義函數 再通過主函數調用實現的

131、。</p><p><b>  主函數:</b></p><p><b>  /* 主控函數*/</b></p><p>  int main(int argc,char* argv[])</p><p><b>  {</b></p><p>  Da

132、taType str[MAXNUM]="\0",input[40];</p><p>  int i,j,flag,start=0,pos,tag1,tag2;</p><p>  TriTree *temp,*tree=NULL;</p><p><b>  while(1)</b></p><p>

133、;<b>  {</b></p><p>  printf("\t歡迎使用家族關系查詢系統(tǒng)!\n");</p><p>  printf("\t請輸入與之匹配的函數和參數,如parent(C)\n");</p><p>  printf("\t 1.新建一個家庭關系: Create(fa

134、milyname) 參數為字符串\n");</p><p>  printf("\t 2.打開一個家庭關系: Open(familyname) 參數為字符串\n");</p><p>  printf("\t 3.添加新成員的信息: Append() 無參數\n");</p>

135、<p>  printf("\t 4.查找一個成員的祖先: Ancesstor(name) 參數為字符串\n");</p><p>  printf("\t 5.查找一個成員的祖先路徑:AncesstorPath(name) 參數為字符串\n");</p><p>  printf("\t 6.確定一個成員是第幾

136、代: Generation(name) 參數為字符串\n");</p><p>  printf("\t 7.查找一個成員的雙親: Parent(name) 參數為字符串\n");</p><p>  printf("\t 8.查找一個成員的兄弟: Brothers(name) 參數為字符串\n"

溫馨提示

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

評論

0/150

提交評論