重建二叉树
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。node
思路:二叉树前序遍历第一个点为根节点,中序遍历顺序为先左子树而后根节点最后右子树。因此先经过前序遍历找出根节点,而后将中序遍历分为左右子树两组,最后对于每一个子树依次递归调用。数组
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]));
二叉树的下一个节点
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点而且返回。注意,树中的结点不只包含左右子结点,同时包含指向父结点的指针。this
思路:根据中序遍历的特色,要找到一个节点的下一个节点无非就是三种状况:一、有右子树,这时只须要把其右孩子做为下一个遍历的(并非要找的)节点,而后沿着该节点的左子树(若是有的话)出发,直到遇到叶子节点,那么该叶子节点就是其下一个要找的节点;二、没有右子树,则判断该节点是不是其父节点的左孩子,若是是则其下一个要找的节点是其父节点;三、若是不是其父节点的左孩子,则把其父节点做为下一个遍历的节点,向上回溯,直到找到父节点没有父节点而且父节点是父节点的父节点的左孩子为止。综合这三种状况就能够找到二叉树中任意一个节点的下一个节点。指针
function TreeNode(x) { this.val = x; this.left = null; this.right = null; this.parent = null; } function getNext(node) { let curNode = null; //第1、判断是否有右孩子 if(node.right != null) { curNode = node.right; while(curNode.left !=null) { curNode = curNode.left; } return curNode; } //第2、判断是不是其父节点的左孩子 if(node.parent == null) { return null; } if(node.parent.left == node) { return node.parent; } //第3、向上找其父节点,直到父节点是其父节点的父节点的左孩子 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); }