树的遍历
定义一棵树,node1为根节点
var node4 = {left: null, right: null, val: 4 };
var node5 = {left: null, right: null, val: 5 };
var node6 = {left: null, right: null, val: 6 };
var node7 = {left: null, right: null, val: 7 };
var node3 = {left: node6, right: node7, val: 3 };
var node2 = {left: node4, right: node5, val: 2 };
var node1 = {left: node2, right: node3, val: 1 };
前序遍历:优先于后代节点
function preorderTraversal(root) {
if (!root) {
return;
}
console.log(root.val);
var left = root.left;
var right = root.right;
left && preorderTraversal(left);
right && preorderTraversal(right);
}
preorderTraversal(node1);//1 2 4 5 3 6 7
中序遍历:从小到大的顺序访问节点
function inorderTraversal(root) {
if (!root) {
return;
}
var left = root.left;
var right = root.right;
left && inorderTraversal(left);
console.log(root.val);
right && inorderTraversal(right);
}
inorderTraversal(node1); //4 2 5 1 6 3 7
后序遍历:后代节点优先于节点本身
function postorderTraversal(root) {
if (!root) {
return;
}
var left = root.left;
var right = root.right;
left && postorderTraversal(left);
right && postorderTraversal(right);
console.log(root.val);
}
postorderTraversal(node1);//4 5 2 6 7 3 1
已知前序、中序,求后序
- 可以知道该树的根节点(前序第一个节点)
- 分析出根节点在中序中的位置,划分出根节点的左子树与右子树
- 根据前序概念画出整个树
- 得到后序遍历
算法:
重建二叉树:
获得后序遍历:/* function TreeNode(x) { this.val = x; this.left = null; this.right = null; } */ function reConstructBinaryTree(pre, vin) { // write code here var result; if(pre.length>1){ var root = pre[0]; var rootIndex = vin.indexOf(root); var vinleft = vin.slice(0,rootIndex); var vinright = vin.slice(rootIndex+1); pre.shift(); var preleft = pre.slice(0,vinleft.length); var preright = pre.slice(vinleft.length); result = { val:root, left:reConstructBinaryTree(preleft,vinleft), right:reConstructBinaryTree(preright,vinright) }; }else if(pre.length === 1){ result = { val:pre[0], left:null, right:null }; } return result; }
function postorderTraversal(root) { if (!root) { return; } var left = root.left; var right = root.right; left && postorderTraversal(left); right && postorderTraversal(right); console.log(root.val); } var pre = ['G','D','A','F','E','M','H','Z']; var vin = ['A','D','E','F','G','H','M','Z']; var tree = reConstructBinaryTree(pre, vin); console.log(postorderTraversal(tree)); // 'A','E','F','D','H','Z','M','G'
已知后序、中序,求前序
- 可以知道该树的根节点(后序最后一个节点)
- 分析出根节点在中序中的位置,划分出根节点的左子树与右子树
- 根据后序概念画出整个树
- 得到前序遍历
算法:
重建二叉树:
获得前序遍历:function reConstructBinaryTree(post, vin) { var result; if(post.length>1){ var root = post[post.length-1]; var rootIndex = vin.indexOf(root); var vinleft = vin.slice(0,rootIndex); var vinright = vin.slice(rootIndex+1); post.pop(); var postleft = post.slice(0,vinleft.length); var postright = post.slice(vinleft.length); result = { val:root, left:reConstructBinaryTree(postleft,vinleft), right:reConstructBinaryTree(postright,vinright) }; }else if(post.length === 1){ result = { val:post[0], left:null, right:null }; } return result; }
function preorderTraversal(root) { if (!root) { return; } console.log(root.val); var left = root.left; var right = root.right; left && preorderTraversal(left); right && preorderTraversal(right); } var post = ['A','E','F','D','H','Z','M','G']; var vin = ['A','D','E','F','G','H','M','Z']; var tree = reConstructBinaryTree(post, vin); console.table(preorderTraversal(tree)); // 'G','D','A','F','E','M','H','Z'