重建二叉树 - 遍历二叉树的三种方式

一时失言乱红尘 2022-12-16 09:27 264阅读 0赞

重建二叉树

输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

示例

前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:

  1. 3
  2. / \
  3. 9 20
  4. / \
  5. 15 7

限制

0 <= 节点个数 <= 5000


二叉树的三种遍历方式

  • 前序遍历,又称为先根遍历(DLR)
  • 中序遍历(LDR)
  • 后续遍历(LRD)(本题没有用到)
    先序遍历序列[pre_start:pre_end]
    中序遍历序列区间[ino_start;ino_end]

这个题的解法是根据先序遍历和中序遍历的规律,在先序遍历的序列中,因为第一个节点一定是根节点cur_root,所以在中序遍历中寻找这个根节点的位置pos,然后以pos为中点,把中序遍历的序列分为两部分:左子树[ino_start:pos-1]、右子树[pos+1:ino_end](相当于把一棵树的根砍掉,分成了两棵树),然后根据pos在原来先序遍历的系列中,也把先序遍历的序列分为两部分:左子树[start+1:pos]、右子树[pos:end]。由此把一个大问题分成了两个子问题,分别在左子树和右子树重复该操作。

解法

  1. struct TreeNode* buildTree(int* preorder, int preorderSize, int* inorder, int inorderSize){
  2. // 明白DLR LVR的意义所在。
  3. // 先序遍历的第一个节点是根节点
  4. struct TreeNode *node = malloc(sizeof(struct TreeNode));
  5. // 记录根节点在中序遍历中的位置
  6. int pos;
  7. int pre_num = 0;
  8. // 如果树节点是0个,返回NULL
  9. if(preorderSize == 0) return NULL;
  10. while(pre_num < preorderSize){
  11. if(inorder[pre_num] == *preorder){
  12. pos = pre_num;
  13. break;
  14. }
  15. pre_num++;
  16. }
  17. node->val = *preorder;
  18. node->left = buildTree(preorder+1,pre_num,inorder,pre_num);
  19. node->right = buildTree(preorder+pos+1,preorderSize-pre_num-1,inorder+pos+1,preorderSize-pre_num-1);
  20. return node;
  21. }

发表评论

表情:
评论列表 (有 0 条评论,264人围观)

还没有评论,来说两句吧...

相关阅读

    相关 顺序】

    1、中序遍历 指对树中任意节点的访问是在遍历完其左子树后进行的,访问此节点后,再对其右子树遍历(左根右)。遍历从根节点开始,遇到每个节点时,其遍历过程为: 中序遍

    相关

    二叉树的遍历分为以下三种: 先序遍历:遍历顺序规则为【根左右】 中序遍历:遍历顺序规则为【左根右】 后序遍历:遍历顺序规则为【左右根】 什么是【根左右】?就是先遍历根,