/*
中序遍历结果 + 前序遍历结果 ==> 生成二叉树
*/
/*
前: A BDE CF
中: DBE A CF
1. 根据前序遍历,确定根节点为A
2. 在中序遍历结果里找到根节点A,A左边则为其左子树,右边则为其右子树
*/
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
typedef struct _Node {
char elem;
_Node* lchild;
_Node* rchild;
_Node() : elem('#'), lchild(NULL), rchild(NULL) { }
} Node;
//递归
Node* buildBTinner(char pre_arr[], int pre_idx_left, int pre_idx_right,
char mid_arr[], int mid_idx_left, int mid_idx_right) {
///
//sleep(1);
if(pre_idx_left > pre_idx_right){
return NULL;
}
if(pre_idx_left == pre_idx_right){
Node* nn = new Node();
nn->elem = pre_arr[pre_idx_left];
return nn;
}
//1. 在前序遍历结果数组中确定当前根节点
char now_root_elem = pre_arr[pre_idx_left];
//2. 在中序遍历结果数组里找到根节点
int k = 0;
while(mid_arr[mid_idx_left + k] != now_root_elem){
k++;
}
printf("%d - %d - %d - %d - %d \n", pre_idx_left, pre_idx_right, mid_idx_left, mid_idx_right, k);
Node* now_root = new Node();
now_root->elem = now_root_elem;
//3. 则中序遍历左半部分为左子树,右半部分为右子树,左子树长度为k
//则前序遍历结果数组中,左子树区间为:[pre_idx_left+1, pre_idx_left+1+k-1]
// 右子树区间为:[pre_idx_left+1+k, pre_idx_right]
now_root->lchild = buildBTinner(pre_arr, pre_idx_left+1, pre_idx_left+k, mid_arr, mid_idx_left, k-1);
now_root->rchild = buildBTinner(pre_arr, pre_idx_left+1+k, pre_idx_right, mid_arr, k+1, mid_idx_right);
}
Node* buildBT(char pre_arr[], int pre_len, char mid_arr[], int mid_len){
return buildBTinner(pre_arr, 0, pre_len-1, mid_arr, 0, mid_len-1);
}
//后序遍历输出
void tailVisit(Node* root){
if(root == NULL){
return;
}
tailVisit(root->lchild);
tailVisit(root->rchild);
printf("%c ", root->elem);
}
int main() {
char pre_arr[6] = {'A','B','D','E','C','F'};
char mid_arr[6] = {'D','B','E','A','C','F'};
Node* root = buildBT(pre_arr, 6, mid_arr, 6);
printf("后序遍历结果为:\r\n ");
tailVisit(root); //D E B F C A
printf("\r\n");
}