// 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;
//二叉树栈
typedef struct{
BtNode * stack[MaxNode]; //栈区
int top; //栈顶指针
}BTreeStack;
//从文件中读取系谱图(以括号表示发储存)
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;
}
//寻找某人的所有孩子函数(递归实现)
bool FindAllSon(BTree r, char e){
if (r == NULL) //递归出口
return false;
if (r->data == e){ //找到该人
BtNode * temp = r->lchild;
if (temp != NULL){
printf("%c的孩子有:",e);
while (temp != NULL){ //循环输出该人的孩子
printf("%c\t", temp->data);
temp = temp->rchild;
}
printf("\n");
}
else
printf("%c没有孩子\n", e);
return true;
}
else{
if (!FindAllSon(r->lchild, e)) //寻找左子树
FindAllSon(r->rchild,e); //左子树未找到时寻找右子树
}
}
//寻找祖先元素(递归实现)
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){ //递归出口,找到该节点
printf("%c祖先元素有:",e);
for (int i = 0; i < bt->top; i++){ //循环输出祖先节点
if (bt->stack[i]->lchild == bt->stack[i + 1])
printf("%c\t",bt->stack[i]->data);
}
printf("\n");
return true;
}
else{
if (!FindAllAncestor(r->lchild, e, bt)){ //在左子树中找改节点
bt->top = temp; //左子树中未找到则退栈
return FindAllAncestor(r->rchild, e, bt); //在右子树中寻找该节点
}
else
return true;
}
}
bool FamilyMemberAdd(){
}
int _tmain(int argc, _TCHAR* argv[])
{
char * familyMapStr = "A(B(D(H,I),E(,J)),C(F(K),G(,L)))";
BTree bt = NULL;
BTreeStack bs;
bs.top = -1;
CreateBTreefromBracketNotation(bt, familyMapStr); //创建家谱二叉树
FindAllSon(bt,'A');
if (!FindAllAncestor(bt, 'K', &bs))
printf("该人的祖先在家谱图中没有得到体现\n");
system("PAUSE");
return 0;
}