当前位置:网站首页>已知两种遍历序列构造二叉树
已知两种遍历序列构造二叉树
2022-07-02 12:12:00 【-小小白-】
二叉树的前序遍历顺序是:先访问根节点,然后前序遍历左子树,再前序遍历右子树。
中序遍历顺序是:中序遍历根节点的左子树,然后是访问根节点,最后中序遍历右子树。
后序遍历顺序是:后续遍历根节点的左子树,然后是后序遍历右子树,最后访问根节点。
一,已知前,中序遍历序列构造二叉树

【主要思路】
1.通过前序遍历,得知根
2.通过中序遍历,得知左子树的长度。
3.就剩下右子树的未知的,就用递归构建
//辅助函数
struct TreeNode* build(int* preorder, int l1, int r1, int* inorder, int l2, int r2){
if (l1 > r1) return NULL;
struct TreeNode* root = (struct TreeNode*)malloc(sizeof(struct TreeNode));
root->val = preorder[l1]; //前序遍历告诉了根在哪里
int mid = l2;
while (inorder[mid] != root->val) mid++;
int leftSize = mid - l2; //中序遍历告诉了左子树的长度(在根之前就是了)
//递归构建
root->left = build(preorder, l1 + 1, l1 + leftSize, inorder, l2, mid - 1);
root->right = build(preorder, l1 + leftSize + 1, r1, inorder, mid + 1, r2);
return root;
}
struct TreeNode* buildTree(int* preorder, int preorderSize, int* inorder, int inorderSize){
return build(preorder, 0, preorderSize - 1, inorder, 0, inorderSize - 1) ;
}二,已知中,后序遍历序列构造二叉树
【主要思路】
1.关键是想清楚后序遍历如何表示左子树、右子树、根
·前序遍历:根/左子树/右子树 -> 根在头
·中序遍历:左子树/根/右子树 -> 左子树的长度
·后序遍历:左子树/右子树/根 -> 根在尾
其中的关系:
用中序遍历定出左子树的长度: leftSize = left_in - mid
前序preorder 中序inorder 后序postorder
左子树 (left_pr + 1, left_pr + leftSize) || (left_in, mid - 1) || (left_po, left_po + leftSize - 1)
右子树 (left_pr + leftSize + 1, right_pr) || (mid + 1, right_in) || (po + leftSize, right_po - 1)
*mid因为是在中序遍历中诞生的,只能在中序遍历中使用
*为什么后序遍历中的左子树要 - 1? 因为这是从“0”开始数的数组,其下标是要“ - 1”
*由此可以推论出前序遍历中的左子树不用 - 1。 因为前序遍历的头是根,使得成为“从1开始”的数组
//辅助函数
struct TreeNode* build(int* inorder, int left_in, int right_in, int* postorder, int left_po, int right_po) {
if (left_in > right_in) return NULL;
struct TreeNode* root = (struct TreeNode*)malloc(sizeof(struct TreeNode));
root->val = postorder[right_po];
int mid = left_in;
while (inorder[mid] != root->val) mid++;
int leftSize = mid - left_in;
root->left = build(inorder, left_in, mid - 1, postorder, left_po, left_po + leftSize - 1);
root->right = build(inorder, mid + 1, right_in, postorder, left_po + leftSize, right_po - 1);
return root;
}
struct TreeNode* buildTree(int* inorder, int inorderSize, int* postorder, int postorderSize){
return build(inorder, 0, inorderSize - 1, postorder, 0, postorderSize - 1);
}三,已知前,后序遍历序列构造二叉树

【主要思路】
1.先把根建好,然后算出左子树的长度,把左子树给建好,最后就是右子树。整个过程可以用递归来实现
2.最终的根很好找,就是前序遍历的第一个。
3.左子树的长度怎么算?可以根据前序遍历和后序遍历的定义,即前序:根->左->右,后序:左->右->根,设mid指针在后序遍历上依次移动,等到mid对应的值等于在前序遍历上根的值,这时的mid减去遍历开始位置的下标再加1,就得到左子树的长度
4.得到了左子树的长度,再除了根,剩下的都是右子树
【注意细节】
1.留意特殊情况,比如前序遍历就只有一个节点
2.用C语言建立节点时,记得要初始化。比如建立了一个root点,记得root->left = NULL, root->right = NULL
//辅助函数
struct TreeNode* build(int* preorder, int left_pr, int right_pr, int* postorder, int left_po, int right_po) {
if (left_pr > right_pr) return NULL; 不能省的特殊情况判断①
struct TreeNode* root = (struct TreeNode*)malloc(sizeof(struct TreeNode)); //C语言建立节点方法
root->val = preorder[left_pr];
root->left = NULL, root->right = NULL; //初始化root节点,省略了这步会报错
if (left_pr == right_pr) return root; //不能省的特殊情况判断②
int mid = left_po;
while (mid < right_po && postorder[mid] != preorder[left_pr + 1]) mid++;
int leftSize = mid - left_po + 1; //得出左子树长度
//递归构建左右子树
root->left = build(preorder, left_pr + 1, left_pr + leftSize, postorder, left_po, mid);
root->right = build(preorder, left_pr + leftSize + 1, right_pr, postorder, mid + 1, right_po - 1);
return root;
}
struct TreeNode* constructFromPrePost(int* preorder, int preorderSize, int* postorder, int postorderSize){
return build(preorder, 0, preorderSize - 1, postorder, 0, postorderSize - 1);
}边栏推荐
- 终于搞懂了JS中的事件循环,同步/异步,微任务/宏任务,运行机制(附笔试题)
- There are 7 seats with great variety, Wuling Jiachen has outstanding product power, large humanized space, and the key price is really fragrant
- Custom exception
- 微信支付宝账户体系和支付接口业务流程
- 04. Some thoughts on enterprise application construction after entering cloud native
- 6092. 替换数组中的元素
- LeetCode_ String_ Simple_ 412.Fizz Buzz
- 【LeetCode】577-反转字符串中的单词 III
- [leetcode] 876 intermediate node of linked list
- [solution] educational codeforces round 82
猜你喜欢

. Solution to the problem of Chinese garbled code when net core reads files

Markdown tutorial

Engineer evaluation | rk3568 development board hands-on test

让您的HMI更具优势,FET-G2LD-C核心板是个好选择

Pytoch saves tensor to Mat file

Basic knowledge of cryptography

密码学基础知识

【LeetCode】1905-统计子岛屿

6.12 critical moment of Unified Process Platform

Pytorch 保存tensor到.mat文件
随机推荐
Semantic segmentation learning notes (1)
损失函数与正负样本分配:YOLO系列
LeetCode_ String_ Simple_ 412.Fizz Buzz
Markdown tutorial
Bing.com网站
Beijing rental data analysis
Case introduction and problem analysis of microservice
6095. 强密码检验器 II
党史纪实主题公益数字文创产品正式上线
Redux - detailed explanation
College entrance examination score line climbing
Force deduction solution summarizes the lucky numbers in 1380 matrix
14_ Redis_ Optimistic lock
Bing.com網站
Guangzhou Emergency Management Bureau issued a high temperature and high humidity chemical safety reminder in July
List of sergeant schools
6092. 替换数组中的元素
基于RZ/G2L | OK-G2LD-C开发板存储读写速度与网络实测
PTA 天梯赛习题集 L2-001 城市间紧急救援
QML pop-up frame, customizable