二叉树前序、中序、后序遍历相互求法 树的遍历

树的遍历

定义一棵树,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

已知前序、中序,求后序

  1. 可以知道该树的根节点(前序第一个节点)
  2. 分析出根节点在中序中的位置,划分出根节点的左子树与右子树
  3. 根据前序概念画出整个树
  4. 得到后序遍历

算法:

重建二叉树:

/* 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'

已知后序、中序,求前序

  1. 可以知道该树的根节点(后序最后一个节点)
  2. 分析出根节点在中序中的位置,划分出根节点的左子树与右子树
  3. 根据后序概念画出整个树
  4. 得到前序遍历

算法:

重建二叉树:

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'




猜你喜欢

转载自blog.csdn.net/u011435776/article/details/80946479
今日推荐