重修二叉树
输入某二叉树的前序遍历和中序遍历的效果,请重修出该二叉树。假定输入的前序遍历和中序遍历的效果中都不含反复的数字。比方输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重修二叉树并返回。
思绪:二叉树前序遍历第一个点为根节点,中序遍历递次为先左子树然后根节点末了右子树。所以先经由过程前序遍历找出根节点,然后将中序遍历分为摆布子树两组,末了关于每一个子树顺次递归挪用。
function TreeNode(x) {
this.val = x;
this.left = null;
this.right = null;
}
//pre为前序遍历序列数组 vin为中序遍历序列数组
function reConstructBinaryTree(pre, vin){
if(pre.length == 0 || vin.length == 0) {
return null;
}
let root = new TreeNode(pre[0]);
//根节点在中序遍历中的位置
let index = vin.indexOf(pre[0]);
let leftPre = pre.slice(1,index+1);//前序左子树
let rightPre = pre.slice(index+1);//前序右子属
let leftVin = vin.slice(0,index);//中序左子树
let rightVin = vin.slice(index+1);//中序右子树
//最先递归
root.left = reConstructBinaryTree(leftPre,leftVin);
root.right = reConstructBinaryTree(rightPre,rightVin);
return root;
}
console.log(reConstructBinaryTree([1,2,4,7,3,5,6,8],[4,7,2,1,5,3,8,6]));
二叉树的下一个节点
给定一个二叉树和个中的一个结点,请找出中序遍历递次的下一个结点而且返回。注重,树中的结点不仅包括摆布子结点,同时包括指向父结点的指针。
思绪:依据中序遍历的特性,要找到一个节点的下一个节点不过就是三种状况:1、有右子树,这时候只需要把其右孩子作为下一个遍历的(并非要找的)节点,然后沿着该节点的左子树(假如有的话)动身,直到碰到恭弘=叶 恭弘子节点,那末该恭弘=叶 恭弘子节点就是其下一个要找的节点;2、没有右子树,则推断该节点是不是是其父节点的左孩子,假如是则其下一个要找的节点是其父节点;3、假如不是其父节点的左孩子,则把其父节点作为下一个遍历的节点,向上回溯,直到找到父节点没有父节点而且父节点是父节点的父节点的左孩子为止。综合这三种状况就能够找到二叉树中恣意一个节点的下一个节点。
function TreeNode(x) {
this.val = x;
this.left = null;
this.right = null;
this.parent = null;
}
function getNext(node) {
let curNode = null;
//第一、推断是不是有右孩子
if(node.right != null) {
curNode = node.right;
while(curNode.left !=null) {
curNode = curNode.left;
}
return curNode;
}
//第二、推断是不是是其父节点的左孩子
if(node.parent == null) {
return null;
}
if(node.parent.left == node) {
return node.parent;
}
//第三、向上找其父节点,直到父节点是其父节点的父节点的左孩子
curNode = node.parent;
while(curNode.parent != null) {
if(curNode == curNode.parent.left) {
return curNode.parent;
}
curNode = curNode.parent;
}
return null;
}
//构建二叉树
let parentNode = createTree(
['a','b','d','e','h','i','c','f','g'],
['d','b','h','e','i','a','f','c','g']);
let i = parentNode.left.right.right;//i节点
let b = parentNode.left;//b节点
let f = parentNode.right.left;//f节点
console.log(getNext(i).val);//a
console.log(getNext(b).val);//h
console.log(getNext(f).val);//c
//依据前序遍历和中序遍历构建一颗二叉树
function createTree(pre,vin){
function TreeNode(x) {
this.val = x;
this.left = null;
this.right = null;
this.parent = null;
}
//pre为前序遍历序列数组 vin为中序遍历序列数组
function reConstructBinaryTree(pre, vin,parent){
if(pre.length == 0 || vin.length == 0) {
return null;
}
let root = new TreeNode(pre[0]);
//根节点在中序遍历中的位置
let index = vin.indexOf(pre[0]);
let leftPre = pre.slice(1,index+1);//前序左子树
let rightPre = pre.slice(index+1);//前序右子属
let leftVin = vin.slice(0,index);//中序左子树
let rightVin = vin.slice(index+1);//中序右子树
//最先递归
root.parent = parent;
root.left = reConstructBinaryTree(leftPre,leftVin,root);
root.right = reConstructBinaryTree(rightPre,rightVin,root);
return root;
}
return reConstructBinaryTree(pre,vin,null);
}