53 # 层序遍历跟反转二叉树

简介: 53 # 层序遍历跟反转二叉树

层序遍历

层序遍历(level order traversal):从上到下,从左到右依次访问每一个节点

// 层序遍历
levelOrderTraversal(visitor) {
    if (this.root === null || visitor == null) return;
    // 根节点放入队列
    let stack = [this.root];
    let index = 0;
    let currentNode = null;
    while ((currentNode = stack[index++])) {
        visitor.visit(currentNode);
        if (currentNode.left) {
            stack.push(currentNode.left);
        }
        if (currentNode.right) {
            stack.push(currentNode.right);
        }
    }
    stack = null;
}

反转二叉树

如图,下面实现反转

// 反转二叉树:用栈实现
invertTree() {
    if (this.root === null) return;
    // 根节点放入队列
    let stack = [this.root];
    let index = 0;
    let currentNode = null;
    while ((currentNode = stack[index++])) {
        // 核心三行就是反转逻辑
        let temp = currentNode.left;
        currentNode.left = currentNode.right;
        currentNode.right = temp;
        if (currentNode.left) {
            stack.push(currentNode.left);
        }
        if (currentNode.right) {
            stack.push(currentNode.right);
        }
    }
    stack = null;
    return this.root;
}
// 反转二叉树:递归
invertTree2(node) {
    if (node !== null) {
        let temp = node.left;
        node.left = node.right;
        node.right = temp;
        this.invertTree(node.left);
        this.invertTree(node.right);
    }
    return node;
}

完整代码

// 节点
class Node {
    constructor(element, parent) {
        this.element = element; // 存的数据
        this.parent = parent; // 父节点
        this.left = null; // 左子树
        this.right = null; // 右子树
    }
}
class BST {
    constructor(compare) {
        this.root = null;
        this.size = 0; // 节点个数
        this.compare = compare || this.compare;
    }
    compare(e1, e2) {
        return e1 - e2;
    }
    // 添加节点
    add(element) {
        // 如果根元素不存在
        if (this.root === null) {
            this.root = new Node(element, null);
            this.size++;
            return;
        } else {
            // 如果根元素存在,那么增加的就不是根节点,需要找到 parent
            let currentNode = this.root;
            // 当前比较的结果
            let compare = 0;
            // 先找到需要对比的 parent(当前父节点)
            let parent = null;
            while (currentNode) {
                parent = currentNode;
                compare = this.compare(element, currentNode.element);
                // 如果大于 0 找右树,小于 0 找左树
                if (compare > 0) {
                    currentNode = currentNode.right;
                } else if (compare < 0) {
                    currentNode = currentNode.left;
                } else {
                    // 如果比较后结果一样,由自己决定是否需要覆盖
                    currentNode.element = element; // 覆盖
                    return;
                }
            }
            // 找到了 parent,生成新节点
            let newNode = new Node(element, parent);
            if (compare > 0) {
                parent.right = newNode;
            } else {
                parent.left = newNode;
            }
        }
    }
    // 先序遍历
    perorderTraversal(visitor) {
        if (visitor == null) return;
        const traversal = (node) => {
            if (node === null) return;
            visitor.visit(node);
            traversal(node.left);
            traversal(node.right);
        };
        traversal(this.root);
    }
    // 中序遍历
    inorderTraversal(visitor) {
        if (visitor == null) return;
        const traversal = (node) => {
            if (node === null) return;
            traversal(node.left);
            visitor.visit(node);
            traversal(node.right);
        };
        traversal(this.root);
    }
    // 后序遍历
    postorderTraversal(visitor) {
        if (visitor == null) return;
        const traversal = (node) => {
            if (node === null) return;
            traversal(node.left);
            traversal(node.right);
            visitor.visit(node);
        };
        traversal(this.root);
    }
    // 层序遍历
    levelOrderTraversal(visitor) {
        if (this.root === null || visitor == null) return;
        // 根节点放入队列
        let stack = [this.root];
        let index = 0;
        let currentNode = null;
        while ((currentNode = stack[index++])) {
            visitor.visit(currentNode);
            if (currentNode.left) {
                stack.push(currentNode.left);
            }
            if (currentNode.right) {
                stack.push(currentNode.right);
            }
        }
        stack = null;
    }
    // 反转二叉树:用栈实现
    invertTree() {
        if (this.root === null) return;
        // 根节点放入队列
        let stack = [this.root];
        let index = 0;
        let currentNode = null;
        while ((currentNode = stack[index++])) {
            // 核心三行就是反转逻辑
            let temp = currentNode.left;
            currentNode.left = currentNode.right;
            currentNode.right = temp;
            if (currentNode.left) {
                stack.push(currentNode.left);
            }
            if (currentNode.right) {
                stack.push(currentNode.right);
            }
        }
        stack = null;
        return this.root;
    }
    // 反转二叉树:递归
    invertTree2(node) {
        if (node !== null) {
            let temp = node.left;
            node.left = node.right;
            node.right = temp;
            this.invertTree(node.left);
            this.invertTree(node.right);
        }
        return node;
    }
}
let bst = new BST();
let arr = [10, 8, 19, 6, 15, 22, 20];
arr.forEach((element) => {
    bst.add(element);
});
console.log(
    bst.levelOrderTraversal({
        visit(node) {
            console.log("visitor.visit---->", node.element);
        },
    })
);
console.dir(bst.invertTree(bst.root), { depth: 100 });
目录
相关文章
|
6月前
排序二叉树的创建及先序、中序、后序输出二叉树
排序二叉树的创建及先序、中序、后序输出二叉树
27 1
|
7月前
二叉树层序遍历及判断完全二叉树
二叉树层序遍历及判断完全二叉树
109 2
|
5天前
|
Java C++ 索引
leetcode-106:从中序与后序遍历序列构造二叉树
leetcode-106:从中序与后序遍历序列构造二叉树
28 0
|
5天前
|
算法 Java 程序员
【算法训练-二叉树 一】【遍历二叉树】前序遍历、中序遍历、后续遍历、层序遍历、锯齿形层序遍历、二叉树右视图
【算法训练-二叉树 一】【遍历二叉树】前序遍历、中序遍历、后续遍历、层序遍历、锯齿形层序遍历、二叉树右视图
45 0
|
6月前
|
存储 算法 C++
【二叉树】利用前序和中序遍历结果生成二叉树并输出其后序和层序遍历结果
【二叉树】利用前序和中序遍历结果生成二叉树并输出其后序和层序遍历结果
65 0
|
11月前
|
C++
力扣 - 106、从中序与后序遍历序列构造二叉树
力扣 - 106、从中序与后序遍历序列构造二叉树
77 0
|
存储
刷题之完全二叉树的权值和小字辈及根据后序和中序遍历输出先序遍历
刷题之完全二叉树的权值和小字辈及根据后序和中序遍历输出先序遍历
121 0
二叉树的锯齿形层序遍历
二叉树的锯齿形层序遍历
|
存储 C++
二叉树的四种遍历方式(前序遍历,中序遍历,后序遍历,层序遍历)C++语言
二叉树的四种遍历方式(前序遍历,中序遍历,后序遍历,层序遍历)C++语言
204 0
|
算法 前端开发 程序员
二叉树的后序遍历序列
二叉树的后序遍历序列
二叉树的后序遍历序列