二叉树 - 序列化与反序列化

/*
中序遍历结果 + 前序遍历结果 ==> 生成二叉树
 */

/*
前: 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");
}





 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值