// FamilyMap_BTree.cpp : 定义控制台应用程序的入口点。

//

#include "stdafx.h"

#define fileName "familyMap.dat"

//定义节点最大个数

#define MaxNode 20

//节点数据类型

typedef char ElemType;

//二叉树节点类型(节点类型)

typedef struct btnode{

ElemType data;//家谱图中人员编号

btnode * lchild;//成员的配偶指针

btnode * rchild;//成员的子女及子女的兄弟指针

}BtNode;

typedef BtNode *BTree;//定义BtNode *类型为BTree

//二叉树栈

typedef struct{

BtNode * stack[MaxNode];//栈区

int top;//栈顶指针

}BTreeStack;

typedef struct{

BtNode * pNode;

int height;

}BtNodewithHeight;

//二叉树队列

typedef struct{

BtNodewithHeight queue[MaxNode];//队列数据区

int front;//队列头指针

int rear;//队列尾指针

}BTreeQueue;

//从文件中读取系谱图(以括号表示法储存)

bool ReadfromFile(char *&s){

FILE *fp = NULL;

fopen_s(&fp,fileName,"rb");

int size=0;

if (fp == NULL)

return false;

fseek(fp, 0L, SEEK_END);

size = ftell(fp);

s = (char *)malloc(sizeof(size+1));//在这里分配了内存空间,在外面使用,最后释放

*(s + size) = '\0';

fread(s,size,1,fp);

fclose(fp);

return true;

}

//从括号表述法创建二叉树(使用栈进行实现)

bool CreateBTreefromBracketNotation(BTree &r, char * btStr){

BTreeStack bts;

bts.top = -1;//初始化栈

int i = 0, k = 0;//i用于保存串的偏移量,k用于标记处理栈顶的左指针还是右指针

char ch;//ch用于保存括号表示法串的字符

BtNode * temp = NULL;//temp用于保存待处理的节点

while ((ch = *(btStr + i)) != '\0')//循环扫描串,并将字符存到ch

{

switch (ch){

case '('://将子树根节点进栈,准备处理根节点左指针

bts.stack[++bts.top] = temp;

k = 1;

break;

case ')'://子树根节点出栈

bts.top--;

break;

case ','://准备处理子树根节点右指针

k = 2;

break;

default://处理数据节点

temp = (BtNode *)malloc(sizeof(BtNode));

temp->data = ch;

temp->lchild = temp->rchild = NULL;

switch (k){

case 0:

r = temp;

break;

case 1:

bts.stack[bts.top]->lchild = temp;

break;

case 2:

bts.stack[bts.top]->rchild = temp;

break;

}

break;

}

i++;

}

return true;

}

//寻找某人的所有孩子函数(递归实现)

//@BTree r表示子树的根节点

//@char e表示要寻找的节点编号

//@bool src储存得到该节点的路径(左还是右) true代表左 false代表右 第一次调用时(即根节点时)src为true

bool FindAllSon(BTree r, char e ,bool src){

if (r == NULL)//递归出口

return false;

if (r->data == e){//找到该人

BtNode * temp=NULL;

if(src==true){//表示该节点为家族外来人,孩子直接挂在他的右子树上

temp=r->rchild;

if(temp==NULL)

printf("%c没有孩子\n",e);

else{

printf("%c的孩子有:\t",e);

while(temp!=NULL){

printf("%c\t",temp->data);

temp=temp->rchild;

}

printf("\n");

}

}else{//表示该节点为家族内部人,孩子挂在他的配偶身上(即左子树的右子树上)

if(r->lchild==NULL)

printf("哥们,%c配偶都没有,哪来的孩子啊...\n",e);

else{

temp=r->lchild->rchild;

if(temp==NULL)

printf("%c还没有孩子\n",e);

else{

printf("%c的孩子有:\t",e);

while(temp!=NULL){

printf("%c\t",temp->data);

temp=temp->rchild;

}

}

}

}

return true;

}

else{

if (!FindAllSon(r->lchild, e, true))//寻找左子树

return FindAllSon(r->rchild,e,false);//左子树未找到时寻找右子树

else

return true;

}

}

//寻找祖先元素(递归实现)

//@BTree r代表根节点

//@char e代表待寻找的元素编号

//@BTreeStack *bt代表记录节点路径信息的栈

bool FindAllAncestor(BTree r, char e, BTreeStack * bt){

if (r == NULL)

return false;//递归出口,未找到该节点

int temp = ++bt->top;//temp储存根节点进栈后的栈顶指针

bt->stack[temp] = r;//将根节点进栈

if (r->data == e){//递归出口,找到该节点,根据路径判断该节点的祖先元素

if(bt->top==0)

printf("%c为该家谱图中的根节点,祖先元素无法找出\n",e);

else{

if(bt->stack[bt->top-1]->lchild==bt->stack[bt->top])

printf("%c是外来人口,根据该家谱图如法得出其祖先元素\n",e);

else{

int k=0;//k记录输出祖先元素的对数

printf("%c的祖先元素有:\t",e);

for(int i=0;itop;i+=2){

if(bt->stack[i]->lchild==bt->stack[i+1]){

k++;

printf("(%c,%c)\t",bt->stack[i]->data,bt->stack[i+1]->data);

}

}

if(k==0)

printf("null\n");

else

printf("\n");

}

}

return true;

}

else{

if (!FindAllAncestor(r->lchild, e, bt)){//在左子树中找改节点

bt->top = temp;//左子树中未找到则退栈

return FindAllAncestor(r->rchild, e, bt);//在右子树中寻找该节点

}

else

return true;

}

}

//以括号表示输出二叉树(递归实现)

void DispbyBracketNotation(BTree r)

{

if(r!=NULL){

printf("%c",r->data);

if(r->lchild!=NULL || r->rchild!=NULL){

printf("(");

DispbyBracketNotation(r->lchild);

if(r->rchild!=NULL)

printf(",");

DispbyBracketNotation(r->rchild);

printf(")");

}

}

}

//求二叉树的高度

int HeightofBTree(BTree r,int h)

{

int lh=h,rh=h;

if(r->lchild!=NULL)

lh=HeightofBTree(r->lchild,h+1);

if(r->rchild!=NULL)

rh=HeightofBTree(r->rchild,h+1);

return lh>=rh?lh:rh;

}

//输出星号函数

void printStar(int n)

{

for(int i=0;i

printf(" * ");

printf("\n");

}

//以凹入表示法输出二叉树

void DispbyIndentation(BTree r,BTreeQueue * q)

{

int h=HeightofBTree(r,1);//获得树的总高度

BtNodewithHeight *p=NULL;

q->queue[++q->rear].pNode=r;//根节点进队

q->queue[q->rear].height=h;

while(q->front!=q->rear){

q->front=(q->front+1)%MaxNode;

p=&(q->queue[q->front]);

if(p->pNode!=NULL){

printf("%c:\t",p->pNode->data);

printStar(p->height);

q->queue[++q->rear].pNode=p->pNode->lchild;

q->queue[q->rear].height=p->height-1;

q->queue[++q->rear].pNode=p->pNode->rchild;

q->queue[q->rear].height=p->height-1;

}

}

}

bool FamilyMemberAdd(){

return false;

}

int _tmain(int argc, _TCHAR* argv[])

{

char * familyMapStr = "A(B(,D(G(,I(,J)),H)),C(E,F))";//树的括号表示法字符串

BTree bt = NULL;//树的根节点指针

BTreeStack bs;//创建二叉树的栈

bs.top = -1;//初始化二叉树栈

BTreeQueue bq;//创建二叉树队列

bq.front=bq.rear=-1;//初始化二叉树队列

char a='F',b='B';

CreateBTreefromBracketNotation(bt, familyMapStr);//创建家谱二叉树

FindAllSon(bt,a,true);//寻找a变量元素的孩子

printf("\n");

if (!FindAllAncestor(bt,b, &bs))//寻找b变量元素的祖先

printf("%c的祖先在家谱图中没有得到体现",b);

printf("\n");

printf("二叉树的括号表示法如下:\n");

DispbyBracketNotation(bt);

printf("\n\n");

printf("二叉树的凹入表示法如下:\n");

DispbyIndentation(bt,&bq);

printf("\n");

//printf("%d\n",HeightofBTree(bt,1));

system("PAUSE");

return 0;

}

/***************************

*说明:

*本例要求给出家谱结构图和家谱性别图

*与本家族节点的配偶必须位于左节点,两人结婚所生小孩须挂于外来人的右子树

*新增节点必须给出性别

*根节点如有配偶则配偶必须出现在家谱图中

*祖先元素输出会包括男与女双方,如果显示祖先元素为空,也表示该图中不存在他的祖先元素

***************************/ 二叉树实现家谱图---未完成

家谱二叉树c语言程序,家谱图-二叉树相关推荐

  1. 先根遍历二叉树c语言程序,二叉树先序遍历C语言实现

    二叉树先序遍历C语言实现 二叉树先序遍历的实现思想是: 访问根节点: 访问当前节点的左子树: 若当前节点无左子树,则访问当前节点的右子树: 以图 1 为例,采用先序遍历的思想遍历该二叉树的过程为: 访 ...

  2. 二叉树c语言程序插入某个成员,关于C ++:二叉树:插入节点算法

    我正在尝试实现二叉树(如果它是普通的二叉树或二叉搜索树,则不重要),并且我在创建节点并将其链接到树的功能上遇到了一些麻烦. 这是我到目前为止编写的代码: class BinaryTree { clas ...

  3. 家谱树c语言程序,Javascript库 - 家谱树流程图

    我定制了一个Graphviz点文件来产生这样的输出.目前我正在编写一个Ruby脚本以从.gedcom文件生成此脚本. 这里的.dot内容,带数字的节点只是点,并以正确的方式流动边缘. digraph ...

  4. C语言家谱管理程序,C语言实现家谱管理

    C语言上实现家谱管理系统 #include #include #include #include #define OK 1 #define ERROR -1 #define STACK_INIT_SI ...

  5. C语言家谱管理程序,c语言的家谱——interesting~

    C++是直接从C语言发展过来的,但最初这种语言不是叫C++,而是C with class,这是由于当时C语言在编程界居于老大的地位,要想发展一种新的语言,最强大的竞争对手就是C语言,所以当时有两个问题 ...

  6. c语言visit函数作用,[求助]二叉树遍历的程序里面的visit函数如何实现

    [求助]二叉树遍历的程序里面的visit函数如何实现 我在没懂的后面加注释 希望大家指教 #include #include #define MAXSIZE 100 typedef struct bi ...

  7. 家族查询系统c语言源程序,家谱管理系统(含源代码).docx

    家谱管理系统(含源代码) 家谱管理系统--C语言(数据结构)目的和要求:树形结构是一种非常重要的非线性结构,它用于描述数据元素之间的层次关系,人类家谱是树形结构的典型体现,通过此项训练让学生掌握树形结 ...

  8. 有序二叉树c语言,二叉搜索树(BST)的实现(C语言)(原创)

    叉搜索树(Binary Search Tree)的一般形式如下图所示,每个节点中的元素大于它的左子树中的所有元素,小于它的右子树中的所有元素.对该图中的二叉树进行中序遍历得到一个从小到大排列的有序序列 ...

  9. C语言:利用排序二叉树进行排序

    C语言:利用排序二叉树进行排序 标签: C语言 二叉树 排序 by 小威威 1.引入 排序二叉树属于二叉树的一种,其主要特色在于构建二叉树与输出二叉树.二叉树的子树很有特点:左子树小于根结点,根结点小 ...

最新文章

  1. 荣耀的鸿蒙系统是什么样的,核心还是备胎?华为鸿蒙系统究竟怎么样了?
  2. 魏少军谈AI芯片热潮和架构创新 透露清华Thinker芯片将独立融资
  3. 团队-团队编程项目作业名称-需求分析
  4. delphi中的第三方控件如何安装
  5. android opencv中图像分割,opencv在android平台下的开发【4】-图像滤波详解
  6. C#基础系列:实现自己的ORM(构造我自己的ORM)
  7. delphi实现延时的方法,很多人首先就想到用timer控件,这里我们不用timer控delphi直接用settimer函数实现延时的方法...
  8. web安全与渗透测试培训全套视频
  9. DoTWeen常用方法
  10. innerHTML和outerHTML区别
  11. 基于SSM框架和JSP的房屋租赁、合同签订系统
  12. 一种全景视频的主观质量评价方法(译)
  13. 英语和汉语的区别10大区别点
  14. 阿里云助力中小企业建站 在线免费自助建站成新用户首选
  15. 获取所有股票历史行情数据
  16. KONG (API网关) 用CORS处理跨域,针对:非简单请求
  17. 正则表达式-贪婪匹配与懒惰匹配之获取短信验证码
  18. 蓝桥云算法题之棋盘放麦子——Python满分解答
  19. c 当前程序的语言,c语言实现获取macos当前的系统语言
  20. Android实现车辆检测(含Android源码 可实时运行)

热门文章

  1. 南方科技大学计算机唐博,唐博 - 教师个人主页 - 南方科技大学
  2. 家乐福中国独立上市,是苏宁的一颗“定心丸”吗?
  3. 现如今社群乱象,社群玩法正解
  4. 三维点云处理06-2D/3DIoU计算
  5. excel 分组排序,取前5
  6. unity 官方案例之刚体控制人物移动
  7. 如何批量删除word文档中表格_word长文档排版:如何快速批量设置样式
  8. 不定宽高,实现盒子左右垂直居中
  9. 彻底解决“你的时钟快了”问题
  10. 【关键字】ddx ddy 导数函数