# 二叉树

# 二叉树遍历


const tree = [
    {
        name: '1',
        children: [
            {
                name: '2',
                children: [
                    { name: '4'},
                    { name: '5' }
                ]
            },
            {
                name: '3',
                children: [
                    null,
                    { name: '6' }
                ]
            },

        ]
    }
]



/**
 * 递归深度优先遍历
 */
function preWalk(node){
    if (node == null) return;

    console.log(node.name) // 放在前面为前序,中间为中序,后面为后序
    preWalk(node.children && node.children[0])
    preWalk(node.children && node.children[1])
}

/**
 * 非递归深度优先遍历
 */
function stackWalk(root) {
    const stack = [];

    let node = root;

    // 只要结点存在
    while (node || stack.length > 0) {

        // 找到最终左结点,压入路径上所有左结点
        while (node) {
            stack.push(node)
            node = node.children && node.children[0]
        }

        // 一旦没有可用的左结点了,开始弹出最后压入的结点,从他的右结点开始遍历
        if (stack.length > 0) {
            node = stack.pop();
            node = node.children && node.children[1]
        }
    }
}




/**
 * 非递归广度优先遍历
**/
function queueWalk(root){

    // 根结点放进队列
    const queue = [root]

    // 只要队列不为空
    while ( queue.length > 0 ) {

        // 就出队
        let node = queue.shift()

        // 压入左结点
        if (node.children && node.children[0]) {
            queue.push(node.children[0])
        }

        // 压入右结点
        if (node.children && node.children[1]) {
            queue.push(node.children[1])
        }
    }
}


# 二叉树与数组互转


/**
 * 二叉树转数组存储
**/
function tree2arr(root) {
    // 数组容器
    const arr = [];

    // 放置节点到数组(指定下标)
    function setNode(node, i) {

        // 如果节点不为空
        if (node) {

            // 放置本节点
            arr[i] = node.name;

            // 放置左、右孩子节点
            let left  = node.children && node.children[0] || null;
            let right = node.children && node.children[1] || null;
            setNode( left,  2 * i + 1);
            setNode( right, 2 * i + 2);
        }
    }

    // 从放置根结点开始
    setNode(root, 0);

    // 返回数组
    return arr;
}

/**
 * 数组还原到二叉树
**/
function arr2tree(arr) {

  	// 获取节点从数组(指定下标)
    function getNode(i){

        // 下标越界或指向元素为空,则返回空
        if (i >= arr.length || arr[i] == null) {
            return null;
        }

        // 构造本节点
        let node = {
            name: arr[i]
        }

        // 获取本结点的左右子节点
        let left  = getNode( 2 * i + 1)
        let right = getNode( 2 * i + 2)

        // 将子节点加到本节点上
        if (left || right) {
            node.children = [];
            node.children[0] = left;
            node.children[1] = right;
        }

        // 返回本节点
        return node;
    }

    // 返回顶节点
    return getNode(0)
}


更新时间: 4/30/2020, 4:20:05 AM