数据结构课程设计家族关系查询系统Word格式.docx

上传人:b****6 文档编号:21567079 上传时间:2023-01-31 格式:DOCX 页数:29 大小:60.67KB
下载 相关 举报
数据结构课程设计家族关系查询系统Word格式.docx_第1页
第1页 / 共29页
数据结构课程设计家族关系查询系统Word格式.docx_第2页
第2页 / 共29页
数据结构课程设计家族关系查询系统Word格式.docx_第3页
第3页 / 共29页
数据结构课程设计家族关系查询系统Word格式.docx_第4页
第4页 / 共29页
数据结构课程设计家族关系查询系统Word格式.docx_第5页
第5页 / 共29页
点击查看更多>>
下载资源
资源描述

数据结构课程设计家族关系查询系统Word格式.docx

《数据结构课程设计家族关系查询系统Word格式.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计家族关系查询系统Word格式.docx(29页珍藏版)》请在冰豆网上搜索。

数据结构课程设计家族关系查询系统Word格式.docx

#defineOK1

#defineERROR-1

#defineINFEASIBLE-1

typedef charDataType;

#defineMAXNUM20

typedef struct TriTNode/*树得三叉链表存储结构*/

ﻩDataType data[MAXNUM];

structTriTNode*parent;

/* 双亲*/

ﻩstruct TriTNode*lchild;

/*左孩子*/

structTriTNode*rchild;

/*右孩子*/

}TriTree;

typedefstructNode/*队列得结点结构*/

{ ﻩ

 TriTree*info;

structNode *next;

}Node;

typedef struct/*链接队列类型定义*/

{ﻩ

 structNode *front;

/*头指针*/

   structNode*rear;

ﻩ /*尾指针*/

}LinkQueue;

DataTypefname[MAXNUM],family[50][MAXNUM];

/*全局变量*/

2、1、2 链队得基本操作

LinkQueue *LQueueCreateEmpty()/*建立一个空队列*/

 LinkQueue*plqu=(LinkQueue*)malloc(sizeof(LinkQueue));

 if(plqu!

=NULL)

   plqu->

front=plqu->rear=NULL;

else

ﻩ{

ﻩﻩprintf("

内存不足!

\n"

);

ﻩreturnNULL;

}ﻩ

  returnplqu;

}

intLQueueIsEmpty(LinkQueue*plqu)/* 判断链接表示队列就是否为空队列*/ 

 return(plqu—>

front==NULL);

voidLQueueEnQueue(LinkQueue *plqu,TriTree *x)/* 进队列*/

{ 

 Node*p=(Node*)malloc(sizeof(Node));

 if(p==NULL)

 printf("

内存分配失败!

\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)/*出队列*/

{

 Node*p;

if(plqu->

front==NULL)

{

ﻩprintf("

队列空!

ﻩ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建立家族关系

2、2、1建立家族关系并存入文件  

基本思想:

首先输入家族关系得名称,以此名称为文件名,建立文本文件接下来按层次输入结点信息,输入一个在文件中写入一行同时将输入得信息保存  

到二位字符数组family中.字符数组family就是全局变量,存储临时信息、 注意,输入时每个结点信息占一行,一个结点有多个兄弟,以“”作为兄弟结束标志,结点若无孩子,直接以“”代替。

依次输入各节点信息,以“#”作为结束标志。

最后使用函数CreateTriTree建立家族关系树、

lixian

liguoyuliguojunliguoqiang

liyongzhiliyongruiliyongming

liwendeliwenjia

   

                         

TriTree*Create(DataTypefamilyname[MAXNUM])/*建立家族关系并存入文件*/

int i=0;

        /* i控制family数组下标*/

DataType ch,str[MAXNUM];

 /* ch存储输入得y或n,str存储输入得字符串*/

ﻩTriTree*t;

ﻩFILE *fp;

strcpy(fname,familyname);

/*以家族名为文本文件名存储*/

ﻩstrcat(fname,"、txt");

fp=fopen(fname,"

r"

);

  /*以读取方式打开文件*/

ﻩif(fp)         /*文件已存在*/

fclose(fp);

ﻩprintf("

%s得家族关系已存在!

重新建立请按“Y”,直接打开请按“N”\n"

,familyname);

ﻩch=getchar();

ﻩgetchar();

  /*接收回车*/

if(ch=='

N'||ch==’n')

ﻩﻩt=Open(familyname);

/*直接打开*/

returnt;

}

}

ﻩif(!

fp||ch=='

Y'

||ch==’y') /* 重新建立,执行以下操作*/

ﻩ{

ﻩfp=fopen(fname,"

w"

  /* 以写入方式打开文件,不存在则新建*/

ﻩprintf(”请按层次输入结点,每个结点信息占一行\n"

ﻩprintf("

兄弟输入结束以“”为标志,结束标志为“#”\n、");

ﻩgets(str);

fputs(str,fp);

ﻩfputc('\n'

fp);

ﻩstrcpy(family[i],str);

 /* 将成员信息存储到字符数组中*/

i++;

       /*family数组下标后移*/

ﻩﻩwhile(str[0]!

='#'

) 

ﻩ{

ﻩﻩﻩprintf("

、");

   /*以点提示符提示继续输入*/

ﻩgets(str);

ﻩfputs(str,fp);

   /*写到文件中,每个信息占一行*/

fputc(’\n'

fp);

ﻩﻩstrcpy(family[i],str);

/*将成员信息存储到字符数组中*/

i++;

   /*family数组下标后移*/

ﻩ}

ﻩfclose(fp);

   /*关闭文件*/

ﻩt=TriTreeCreate();

 /*根据family数组信息创建三叉树*/

ﻩprintf("家族关系已成功建立!

returnt;

  /* 返回树*/

2、2、2建立家族关系树

采用指针数组作为指针,保存输入得结点地址。

队列得尾指针指向当前结点。

头指针指向当前结点得双亲结点。

输入得结点信息已存储在字符数组family中.

将信息复制到字符串数组“ch”中 ,如果"ch"

不就是“”,则建立一个新结点。

若新结点就是第一个结点,则它就是根结点,将其入队,指针tree指向这个根节点;

如果不就是根结点,则将当前结点链接到双亲结点上,即当前结点得双亲指针就就是队头元素,然后将当前结点入队列。

接着判断flag得值,如果flag=0,表示当前结点没有左孩子,那么当前结点就就是双亲得左孩子。

否则,当前结点就就是双亲得右孩子。

用指针root指向刚刚入队得结点。

继续复制数组family得下个元素。

如果“ch"

就是.则flag=0(因为“"

后面得第一个孩子为左孩子),同时判断“”就是否就是第一次出现,如果就是第一次,则令标志star=1;

如果不就是第一次出现.则出队列,root指向队头元素(实际上root总就是指向双亲结点)。

继续复制family得下一个元素。

知道遇到“#”结束.函数返回指针tree。

 /*建立家族关系树*/

TriTree *TriTreeCreate()

TriTree*t,*x=NULL,*tree,*root=NULL;

LinkQueue*q=LQueueCreateEmpty();

/*建立一个空得队列,存储指向树得指针*/

ﻩinti=0,flag=0,start=0;

ﻩDataTypestr[MAXNUM];

   /*存放family数组中信息*/

ﻩstrcpy(str,family[i]);

     /*复制*/

i++;

         /*family数组下标后移*/

ﻩwhile(str[0]!

=’#'

)  /*没遇到结束标志继续循环*/

ﻩﻩwhile(str[0]!

='

’) /*没遇到兄弟输入结束标志继续*/

ﻩ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(t—>

data,str);

ﻩﻩt—〉lchild=NULL;

ﻩﻩﻩt—>rchild=NULL;

ﻩﻩﻩt-〉parent=LQueueGetFront(q);

    /*当前结点得双亲为队头元素*/

ﻩﻩLQueueEnQueue(q,t);

    /*入队*/

ﻩif(!

flag)      /*flag为,当前结点没有左孩子*/

ﻩﻩroot—〉lchild=t;

ﻩelse/*flag为,当前结点已有左孩子*/

ﻩroot-〉rchild=t;

ﻩﻩﻩroot=t;

   /*root指向新得结点t*/

ﻩﻩflag=1;

    /* 标记当前结点已有左孩子*/

ﻩﻩstrcpy(str,family[i]);

 

ﻩﻩﻩi++;

if(start!

=0)    /*标记不就是第一次出现“”*/

ﻩ{

ﻩﻩﻩLQueueDeQueue(q,x);

    /*出队*/

ﻩﻩif(q->

front!

=NULL)

ﻩﻩﻩroot=LQueueGetFront(q);

/*root为队头元素*/

ﻩﻩ}

ﻩstart=1;

    /*标记已出现过“”*/

flag=0;

      /*“”后面得结点一定为左孩子*/

ﻩﻩstrcpy(str,family[i]);

ﻩi++;

ﻩreturntree;

     /* 返回树*/

2、3打开一个家族关系 

首先输入家族关系名,以家族名为文件名打开文件,如果家族关系不存在,返回空;

如果存在,文件打开,读取文件。

将文件得每行信息依次存储在数组family【】中。

/*打开一个家族关系*/

TriTree*Open(DataTypefamilyname[MAXNUM])

ﻩinti=0,j=0;

ﻩDataTypech;

FILE*fp;

ﻩTriTree*t;

strcpy(fname,familyname);

strcat(fname,"、txt”);

ﻩfp=fopen(fname,"

r");

   /*以读取方式打开文件*/

ﻩif(fp==NULL)    /* 文件不存在*/

ﻩprintf(”%s得家族关系不存在!

,familyname);

ﻩreturn NULL;

else

ﻩch=fgetc(fp);

    /*按字符读取文件*/

ﻩﻩwhile(ch!

=EOF)   /*读到文件尾结束*/

{

ﻩif(ch!

='\n'

)  /* ch不为一个结点信息得结尾*/

ﻩ{

ﻩﻩﻩfamily[i][j]=ch;

 /*将文件信息存储到family数组中*/

ﻩﻩﻩﻩj++;

    

ﻩelse

ﻩ{

ﻩﻩfamily[i][j]=’\0'

;

/*字符串结束标志*/

ﻩﻩi++;

 /* family数组行下标后移*/

ﻩﻩj=0;

      /* family数组列下标归零*/

ﻩ}

ﻩch=fgetc(fp);

  /* 继续读取文件信息*/

ﻩ}

ﻩﻩfclose(fp);

    /*关闭文件*/

ﻩﻩt=TriTreeCreate(family);

/*调用函数建立三叉链表*/

ﻩﻩprintf("

家族关系已成功打开!

\n”);

ﻩﻩreturnt;

ﻩ}

2、4在家族关系中查找一个成员就是否存在

用递归算法实现。

如果树空,返回NULL.如果根节点就就是要查找得成员,返回根节点;

否则,递归查找它得左右子树.

/*查找一个成员就是否存在*/

TriTree*Search(TriTree *t,DataTypestr[])

{ﻩ

TriTree*temp;

if(t==NULL)     /* 如果树空则返回NULL*/

return NULL;

ﻩelseif(strcmp(t-〉data,str)==0)/* 如果找到返回该成员指针*/

ﻩreturnt;

   

else /*如果没找到遍历左右子树进行查找*/

ﻩtemp=Search(t—>lchild,str);

/*递归查找*/

if(temp)     /*结点不空则查找*/

ﻩﻩreturn(Search(t->lchild,str));

ﻩﻩelse

ﻩreturn(Search(t—>

rchild,str));

2、5向家族中添加一个新成员

添加得新成员要根据其双亲确定其在家族中得位置.首先判断该双亲就是否在此家族关系中,若存在则查找其双亲,将新结点插入其双亲得最后一个孩子之后;

若没有孩子,则直接作为左孩子插入。

以写入得方式打开文件,如果成功打开,则更新family数组中得信息,并查找新成员得双亲所在位置与其对应得“"

个数,如果“”个数小于双亲位置,则添加“”实质相等,新成员不插入到最后“”之前。

最后将family数组中信息写入文件保存,关闭文件.

/*添加一个新成员*/

voidAppend(TriTree *t)

ﻩinti=0,j,parpos=1,curpos,num,end=0,count=-1;

ﻩDataType chi[MAXNUM],par[MAXNUM];

/*存储输入得孩子与其双亲结点*/

ﻩTriTree*tpar,*temp;

ﻩFILE*fp;

ﻩprintf(”请输入要添加得成员与其父亲,以回车分隔!

\n、");

gets(chi);

printf(”、”);

 /*以点提示符提示继续输入*/

gets(par);

tpar=Search(t,par);

/*查找双亲结点就是否存在*/

if(!

tpar)

ﻩﻩprintf(”%s该成员不存在!

\n");

else  /* 存在则添加其孩子*/

ﻩtemp=(TriTree*)malloc(sizeof(TriTree));

/*申请空间*/

temp->parent=tpar;

     

ﻩstrcpy(temp-〉data,chi);

temp—>

lchild=NULL;

   /*新结点左右孩子置空*/

ﻩtemp—>

rchild=NULL;

ﻩﻩif(tpar->

lchild)ﻩ   /*成员存在左孩子*/

ﻩﻩ{

ﻩtpar=tpar->

lchild;

 /* 遍历当前成员左孩子得右子树*/

ﻩﻩwhile(tpar—〉rchild)ﻩ/*当前结点右孩子存在*/

ﻩtpar=tpar—>

rchild;

    /*继续遍历右孩子*/

ﻩtpar->

rchild=temp;

    /*将新结点添加到所有孩子之后*/

}     

ﻩﻩelse      /*没有孩子则直接添加*/

ﻩtpar—〉lchild=temp;

ﻩfp=fopen(fname,”w”);

 /*以写入方式打开文件*/

ﻩif(fp)

ﻩwhile(strcmp(par,family[i])!

=0&&family[i][0]!

=’#’)

ﻩﻩﻩ{

ﻩﻩﻩif(family[i][0]!

'

)   /*查找双亲在数组中位置*/

ﻩﻩﻩﻩﻩparpos++;

    /* parpos计数*/

ﻩi++;

   /* family数组行下标后移*/

ﻩﻩﻩ}

i=0;

        /*family数组行下标归*/

while(family[i][0]!

{

ﻩﻩif(family[i][0]==’’) /*查找“"

得个数,第一个不计*/

ﻩﻩcount++;

   /*count累加个数*/

ﻩﻩif(count==parpos)   /*说明此“"

与其前一个“"

之前为par得孩子*/

ﻩﻩﻩcurpos=i;

/* curpos计当前位置*/

ﻩﻩﻩi++;

   /* family数组行下标后移*/

ﻩ}

ﻩﻩﻩif(count<

parpos)  /*“”数小于parpos数*/

ﻩﻩﻩﻩnum=parpos—count;

/*添加“”个数为num */

ﻩﻩﻩfor(j=i;

j<=i+num;

j++)/*从数组末尾添加“"

*/

ﻩﻩﻩstrcpy(family[j],"\0”);

 

ﻩstrcpy(family[i+num+1],"

#\0”);

/* “#”移到数组末尾*/ 

ﻩstrcpy(family[i+num-1],chi);

 /*在最后一个“”前添加新成员*/ 

ﻩﻩend=1;

      /*end为时标记已添加*/

ﻩﻩfor(j=i;

j>

=curpos;

j——)  /*当前位置到数组最后得全部信息后移一行*/

ﻩﻩstrcpy(family[j+1],family[j]);

ﻩﻩﻩstrcpy(family[curpos],chi);

/*将新结点存储到“”得前一行*/

ﻩif(end==1) /*若end为,则数组末尾下标后移num位*/

ﻩﻩﻩﻩi=i+num;

ﻩfor(j=0;

j〈=i+1;

j++) /*将数组所有信息写入文件*/

ﻩfputs(family[j],fp);

ﻩﻩﻩfputc('

\n'

,fp);

  /*一个信息存一行*/

ﻩ}

ﻩfclose(fp);

    /* 关闭文件*/

ﻩﻩprintf("添加新成员成功!

ﻩ}

ﻩelse

ﻩﻩprintf(”添加新成员失败!

\n");

2、6家族成员关系得相关查询

2、6、1查找一个家族得鼻祖

判断输入得姓名就是否在该家族中存在,如果存在,则返回该家族得根节点信息。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1