原创

二叉树的遍历算法


前言

不了解二叉树,请移步这篇文章 二叉树的理解 https://web03.cn/blog/25

二叉树结构图

二叉树js对象表示

let binaryTree = {
    value: "-",
    left: {
        value: "+",
        left: {
            value: "a"
        },
        right: {
            value: "*",
            left: {
                value: "b"
            },
            right: {
                value: "c"
            }
        }
    },
    right: {
        value: "/",
        left: {
            value: "d"
        },
        right: {
            value: "e"
        }
    }
}

以上二叉树遍历结果

前序遍历:- + a * b c / d e
中序遍历:a + b * c - d / e
后序遍历:a b c * + d e / -
广度遍历:- + / a * d e b c

1. 前序(深度)遍历-递归

function iterator1(tree){
    let arr = []
    function f(node) {
        if (!node) return
        arr.push(node.value)
        f(node.left)
        f(node.right)
    }
    f(tree)
    return arr
}
let result1 = iterator1(binaryTree)
console.log("前序遍历-递归",result1)
//  ["-", "+", "a", "*", "b", "c", "/", "d", "e"]

2. 前序(深度)遍历 非递归

function iterator2(tree) {
    let stack = [];
    stack.push(tree);
    let arr = []
    while (stack.length !== 0) {
        let node = stack.shift();
        arr.push(node.value);
        node.right && stack.unshift(node.right);
        node.left && stack.unshift(node.left);
    }
    return arr
}
let result2 = iterator2(binaryTree)
console.log("前序遍历 非递归",result2)
//  ["-", "+", "a", "*", "b", "c", "/", "d", "e"]

3. 中序遍历 递归

function iterator3(tree){
    let arr = []
    function f(node) {
        if (!node) return
        f(node.left)
        arr.push(node.value)
        f(node.right)
    }
    f(tree)
    return arr
}
let arr3 = iterator3(binaryTree)
console.log("中序遍历 递归",arr3)
//["a", "+", "b", "*", "c", "-", "d", "/", "e"]

4. 中序遍历 非递归

function iterator4(tree) {
    let stack = []
    let t = tree
    let arr = []
    while (t||stack.length !==0){
        while (t){
            stack.push(t)
            t=t.left
        }
        t = stack.pop()
        arr.push(t.value)
        t=t.right
    }
    return arr
}
let arr4 = iterator4(binaryTree)
console.log("中序遍历 非递归",arr4)
//["a", "+", "b", "*", "c", "-", "d", "/", "e"]

5. 后序遍历 递归

function iterator5(tree){
    let arr = []
    function f(node) {
        if (!node) return
        f(node.left)
        f(node.right)
        arr.push(node.value)
    }
    f(tree)
    return arr
}
let arr5 = iterator5(binaryTree)
console.log("后序遍历 递归",arr5)
// ["a", "b", "c", "*", "+", "d", "e", "/", "-"]

6. 后序遍历 非递归

function iterator6(tree) {
    let arr = [];
    let stack = [];
    stack.push(tree);
    while(stack.length) {
        if(tree.left && !tree.touched) {
            tree.touched = 'left';
            tree = tree.left;
            stack.push(tree);
            continue;
        }
        if(tree.right && tree.touched !== 'right') {
            tree.touched = 'right';
            tree = tree.right;
            stack.push(tree);
            continue;
        }
        tree = stack.pop();
        tree.touched && delete tree.touched;
        arr.push(tree.value);
        tree = stack.length ? stack[stack.length - 1] : null;
    }
    return arr;
}
let arr6 = iterator6(binaryTree)
console.log("后序遍历 非递归",arr6)
// ["a", "b", "c", "*", "+", "d", "e", "/", "-"]

7. 广度遍历 递归

function iterator7(tree) {
    let arr = [];
    let stack = [tree]; // 先将要遍历的树压入栈
    let count = 0; // 用来记录执行到第一层
    function f() {
        let node = stack[count];
        if(node) {
            arr.push(node.value);
            if(node.left) stack.push(node.left);
            if(node.right) stack.push(node.right);
            count++;
            f();
        }
    }
        f(tree)
    return arr
}
let result7 = iterator7(binaryTree)
console.log("广度遍历 递归",result7)
//["-", "+", "/", "a", "*", "d", "e", "b", "c"]

8. 广度遍历 非递归

function iterator8(tree) {
    let stack = []
    stack.push(tree)
    let arr=[]
    while (stack.length !== 0){
        let node = stack.shift()
        arr.push(node.value)
        node.left && stack.push(node.left)
        node.right && stack.push(node.right)
    }
    return arr
}
let result8 = iterator8(binaryTree)
console.log("广度遍历 非递归",result8)
// ["-", "+", "/", "a", "*", "d", "e", "b", "c"]

翻转二叉树

如果根节点不为空,那么将左右子结点交换,然后将左右子结点进行递归调用

function flipTree(tree) {
    if (tree){
        let node = tree.right
        tree.left && (tree.right = tree.left)
        node && (tree.left = node)
        flipTree(tree.left)
        flipTree(tree.right)
    }
    return tree
}
let result9 = flipTree(binaryTree)
console.log("翻转二叉树",result9)

翻转前结构图

翻转后结构图

翻转前数据

let binaryTree = {
    value: "-",
    left: {
        value: "+",
        left: {
            value: "a"
        },
        right: {
            value: "*",
            left: {
                value: "b"
            },
            right: {
                value: "c"
            }
        }
    },
    right: {
        value: "/",
        left: {
            value: "d"
        },
        right: {
            value: "e"
        }
    }
}

翻转后数据

    let result9 = {
        value: "-",
        left: {
            value: "/",
            left: {
                value: "e"
            },
            right: {
                value: "d"
            }
            },
        right: {
            value: "+",
            left: {
                value: "*",
                left: {
                    value: "c"
                },
                right: {
                    value: "b"
                }
                },
            right: {
                value: "a"
            }
        }
    }
JavaScript
算法技巧
  • 作者:零三(联系作者)
  • 最后更新时间:2020-06-12 19:18
  • 版权声明:自由转载-非商用-非衍生-保持署名
  • 转载声明:来源地址 https://web03.cn