前言
一道关于树的算法题,记载下来,以便复习
要了解一些关于树的知识点
图上一颗简单的树的遍历结果
先序遍历:(根-左-右) (A - B - D - E - C - F)
中序遍历:(左-根-右) (D - B - E - A - F - C)
后序遍历:(左-右-根) (D - E - B - F - C - A)
算法题问到的是:输入先序遍历和中序遍历,重构一棵2叉树
想法如下,当你知道先序遍历后,可以确定这棵树的根节点
先序遍历:(根-左-右) (A - B - D - E - C - F) && 中序遍历:(左-根-右) (D - B - E - A - F - C)
这棵树的根节点是A
根据中序遍历确定A的左子树为D - B - E
,右子树为F - C
然后将左子树和右子树进行一个递归就可以轻松解决这个问题了
代码如下
/**
* @param {first[]} first
* @param {middle[]} middle
* @return {number[]}
*/
/* function TreeNode(x) {
this.val = x;
this.left = null;
this.right = null;
} */
// 定义一个函数,接受先序和中序2个参数
function newTree(first, middle){
// 这里首先要对数据进行一个判断,如果前序遍历为空时退出,这个时候说明没有节点了,为什么要思考一下
if (first.length === 0) return;
// 接着定义一个根节点 和 一个根节点的下标
let root = new TreeNode(first[0]) // 根节点
let root_index = middle.indexof(root.val) // 拿到中序遍历中根节点的下标
root.left = newTree(first.slice(1,root_index+1), middle.slice(0,root_index))
root.right = newTree(first.silce(root_index+1), middle.slice(root_index+1))
// 说一下为什么这样传,左节点要的是左左子树,根据拿到的根节点下标,分别把左右子树进行切割传入
return root
}
这里用了一个对象来储存树,在每一个this.left和this.right中都会有一个树的对象存在,直到这个节点不存在数据
{
this.val // 根
this.left:{ //左节点
this.val // 根
this.left // 左节点
this.right // 右节点
}
this.right // 右节点同理
}
这个是网上的解法,特意记录下来,以便复习,并在思考有没有更好的解法,如果有错,欢迎指出