采用二叉树来表示一个家谱关系,一个家谱可表示为一颗树。如下图为红楼梦家谱的一部分:
通过将家谱树结构(上图)转换为对应的二叉树(下图),从而可以通过二叉树对应的括号表达式复原构建二叉树,完成对树的遍历,以及查询某个树节点的所有长辈节点。
实验要求:
- 输入一颗二叉树的括号表示法,完成树的构建。
- 使用后序遍历递归算法遍历二叉树并输出。
- 使用先序遍历非递归算法遍历二叉树并输出。
- 指定家谱中的某一成员,输出其所有长辈。
运行示例:
程序源码:
#include <stdio.h>
#include <stdlib.h>
typedef struct TreeNode
{
char data;
struct TreeNode *left;
struct TreeNode *right;
} TreeNode;
/**
* 构建二叉树
*/
TreeNode *createBinaryTree(const char s[100]);
/**
* 后序递归遍历二叉树
*/
void postRecurOrder(TreeNode *root);
/**
* 先序非递归遍历二叉树
*/
void preOrder(TreeNode *root);
/**
* 查询某个节点的所有长辈
*/
void findFather(TreeNode *tree, char target);
int main()
{
char s[100];
printf("请输入括号表达式表示的二叉树结构:");
gets_s(s);
// 根据括号表达式复原构建二叉树
TreeNode *binaryTree = createBinaryTree(s);
printf("\n先序遍历非递归算法输出:");
preOrder(binaryTree);
printf("\n后序遍历递归算法输出:");
postRecurOrder(binaryTree);
printf("\n\n请输入指定人物代号,以查询其所有长辈:");
char target;
scanf("%c", &target);
printf("\n%c 的所有长辈为:", target);
findFather(binaryTree, target);
printf("\n\n");
return 0;
}
TreeNode *createBinaryTree(const char s[100])
{
TreeNode *root = NULL, *tempRoot = NULL, *nodeArray[100];
int top = -1, brackets = 0;
for (int j = 0; s[j] != '\0'; j++)
{
if (s[j] == '(')
{
// 遇到左括号,表示下一个遇到的字符为左孩子,则 brackets=1
top++;
nodeArray[top] = tempRoot;
brackets = 1;
}
else if (s[j] == ')')
{
// 遇到右括号表示该块读取完成
top--;
}
else if (s[j] == ',')
{
// 遇到逗号,表示下一个遇到的字符为右孩子,则 brackets=2
brackets = 2;
}
else
{
// 遇到字符,则通过 brackets 的值,设置父节点的左、右孩子节点
tempRoot = (TreeNode *)malloc(sizeof(TreeNode));
tempRoot->data = s[j];
tempRoot->right = tempRoot->left = NULL;
if (root == NULL)
root = tempRoot;
else if (brackets == 1)
nodeArray[top]->left = tempRoot;
else
nodeArray[top]->right = tempRoot;
}
}
return root;
}
void postRecurOrder(TreeNode *root)
{
if (root != NULL)
{
postRecurOrder(root->left);
postRecurOrder(root->right);
printf("%c", root->data);
}
}
void preOrder(TreeNode *root)
{
TreeNode *a[100], *p;
int i = -1;
if (root != NULL)
{
i++;
a[i] = root;
while (i > -1)
{
p = a[i];
i--;
printf("%c", p->data);
if (p->right != NULL)
{
i++;
a[i] = p->right;
}
if (p->left != NULL)
{
i++;
a[i] = p->left;
}
}
}
}
void findFather(TreeNode *tree, char target)
{
TreeNode *a[100], *p;
if (tree != NULL)
{
int i = 0;
a[i] = tree;
p = tree;
while (p->data != target)
{
i++;
a[i] = p->left;
p = a[i];
if (p->left == NULL && p->data != target)
{
printf("您输入的指令有误\n");
break;
}
}
i = i - 1;
while (i >= 0)
{
p = a[i];
printf("%c", p->data);
while (p->right != NULL)
{
p = p->right;
printf("%c", p->data);
}
i--;
}
}
}