程序说明
一、输入输出说明
-
输入:该程序输入分两行,第一行为对这棵二叉树(记为BinaryTree)进行前序遍历所得的序列,第二行为对BinaryTree进行中序遍历所得的序列。结点元素之间均用空格隔开。
Sample InputA B D C E F B D A E F C
-
输出:该程序输出按树状打印的BinaryTree
Sample OutputC F E A D B
二、程序实现思路
-
结点类型:结点用程序描述为一个结构体 TreeNode,其中包含该结点的键值 key,深度 depth及指向左、右孩子的指针 left_child,right_child
struct TreeNode { struct TreeNode* left_child; struct TreeNode* right_child; char key; int depth; };
-
函数及其功能:
- main:主函数,读入数据并构建二叉树,而后对其进行逆中序遍历并打印
- ConstructBinTree:根据前序序列和中序序列构建二叉树,并返回该二叉树的根节点root。输入为该二叉树的前序序列preorder及中序序列inorder,返回值为指向根节点的指针TreeNode*
实现思路即为练习7.11答案,即: - PrintTreeWithRotation:打印该二叉树。输入为该二叉树的根节点,无返回值。
实现思路即对其进行反向中序遍历(RightChild -> Root -> LeftChild)
可利用递归实现或利用栈作为辅助数据结构进行非递归实现。此处采用编码难度较低但效率较低的递归实现。
三、代码实现
/*
* @Description:
* Input: the inorder and preorder traverse sequence of the binary tree
* @Author: Fishermanykx
* @Date: 2019-11-9 22:18:42
* @LastEditors: Fishermanykx
* @LastEditTime: 2019-11-13 12:58:37
*/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct TreeNode {
struct TreeNode* left_child;
struct TreeNode* right_child;
char key;
int depth;
};
typedef struct TreeNode* Node;
Node ConstructBinTree(char preorder[], char inorder[], int pre_lo, int pre_hi,
int in_lo, int in_hi, int depth);
void PrintTreeWithRotation(Node bin_tree);
int main() {
// 数据读入
char pre_order_tree[100];
char in_order_tree[100];
char tmp_str[100];
char ch;
// 读入前序序列
gets(tmp_str);
int tree_size = 0;
for (int i = 0; i < strlen(tmp_str); ++i) {
if (isalpha(tmp_str[i])) pre_order_tree[tree_size++] = tmp_str[i];
}
// 读入中序序列
gets(tmp_str);
tree_size = 0;
for (int i = 0; i < strlen(tmp_str); ++i) {
if (isalpha(tmp_str[i])) in_order_tree[tree_size++] = tmp_str[i];
}
// 构建二叉树
Node root = ConstructBinTree(pre_order_tree, in_order_tree, 0, tree_size - 1,
0, tree_size - 1, 1);
// 打印二叉树(逆中序遍历)
PrintTreeWithRotation(root);
return 0;
}
Node ConstructBinTree(char preorder[], char inorder[], int pre_lo, int pre_hi,
int in_lo, int in_hi, int depth) {
Node root = (Node)malloc(sizeof(struct TreeNode));
root->depth = depth;
++depth;
root->key = preorder[pre_lo];
// 在中序序列中找到root
int root_index;
for (root_index = in_lo; inorder[root_index] != root->key; ++root_index)
;
int left_subtree_size = root_index - in_lo;
int right_subtree_size = in_hi - root_index;
if (left_subtree_size > 0) {
root->left_child = ConstructBinTree(preorder, inorder, pre_lo + 1,
pre_lo + left_subtree_size, in_lo,
root_index - 1, depth);
} else {
root->left_child = NULL;
}
if (right_subtree_size > 0) {
root->right_child = ConstructBinTree(
preorder, inorder, pre_lo + left_subtree_size + 1,
pre_hi - right_subtree_size + 1, root_index + 1, in_hi, depth);
} else {
root->right_child = NULL;
}
return root;
}
/**
* @description: Anti-InOrderTraverse
* @param {type}
* @return:
*/
void PrintTreeWithRotation(Node bin_tree) {
if (bin_tree) {
if (bin_tree->right_child) {
PrintTreeWithRotation(bin_tree->right_child);
printf("\n");
}
for (int i = 0; i < bin_tree->depth; ++i) {
printf("\t");
}
printf("%c\n", bin_tree->key);
if (bin_tree->left_child) {
PrintTreeWithRotation(bin_tree->left_child);
printf("\n");
}
}
}
四、测试输入及输出
-
测试输入1
A B D C E F B D A E F C
输出1
C F E A D B
-
测试输入2
A B D H I E J C F G H D I B E J A F C G
输出2
G C F A J E B I D H