js 深度遍历方法

在 JavaScript 中,深度遍历(Depth-First Search, DFS)通常用于遍历树或图结构。深度遍历会沿着一个分支尽可能深地访问节点,直到到达叶子节点,然后再回溯到上一个节点,继续遍历其他分支。

以下是几种常见的深度遍历方法:

1. 递归实现

递归是实现深度遍历的最简单方法。以下是一个递归实现的深度遍历示例:

function dfs(node, callback) {
    if (node === null) return;

    // 访问当前节点
    callback(node);

    // 递归遍历子节点
    if (node.children) {
        for (let child of node.children) {
            dfs(child, callback);
        }
    }
}

// 示例用法
const tree = {
    value: 1,
    children: [
        {
            value: 2,
            children: [
                { value: 4, children: [] },
                { value: 5, children: [] }
            ]
        },
        {
            value: 3,
            children: [
                { value: 6, children: [] }
            ]
        }
    ]
};

dfs(tree, node => console.log(node.value));
// 输出: 1, 2, 4, 5, 3, 6

2. 使用栈的非递归实现

递归方法虽然简单,但在处理深度较大的树时可能会导致栈溢出。可以使用栈来实现非递归的深度遍历。

function dfs(root, callback) {
    if (root === null) return;

    const stack = [root];

    while (stack.length > 0) {
        const node = stack.pop();

        // 访问当前节点
        callback(node);

        // 将子节点逆序压入栈中,保证左子节点先被访问
        if (node.children) {
            for (let i = node.children.length - 1; i >= 0; i--) {
                stack.push(node.children[i]);
            }
        }
    }
}

// 示例用法
const tree = {
    value: 1,
    children: [
        {
            value: 2,
            children: [
                { value: 4, children: [] },
                { value: 5, children: [] }
            ]
        },
        {
            value: 3,
            children: [
                { value: 6, children: [] }
            ]
        }
    ]
};

dfs(tree, node => console.log(node.value));
// 输出: 1, 2, 4, 5, 3, 6

3. 前序、中序、后序遍历

对于二叉树,深度遍历可以分为前序遍历、中序遍历和后序遍历:

  • 前序遍历:根节点 -> 左子树 -> 右子树

  • 中序遍历:左子树 -> 根节点 -> 右子树

  • 后序遍历:左子树 -> 右子树 -> 根节点

以下是二叉树的深度遍历实现:

class TreeNode {
    constructor(value) {
        this.value = value;
        this.left = null;
        this.right = null;
    }
}

// 前序遍历
function preOrder(node, callback) {
    if (node === null) return;
    callback(node.value);
    preOrder(node.left, callback);
    preOrder(node.right, callback);
}

// 中序遍历
function inOrder(node, callback) {
    if (node === null) return;
    inOrder(node.left, callback);
    callback(node.value);
    inOrder(node.right, callback);
}

// 后序遍历
function postOrder(node, callback) {
    if (node === null) return;
    postOrder(node.left, callback);
    postOrder(node.right, callback);
    callback(node.value);
}

// 示例用法
const root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.left = new TreeNode(4);
root.left.right = new TreeNode(5);
root.right.left = new TreeNode(6);

preOrder(root, value => console.log(value)); // 输出: 1, 2, 4, 5, 3, 6
inOrder(root, value => console.log(value));  // 输出: 4, 2, 5, 1, 6, 3
postOrder(root, value => console.log(value)); // 输出: 4, 5, 2, 6, 3, 1

总结

  • 递归实现:简单直观,但可能栈溢出。

  • 非递归实现:使用栈模拟递归,适合深度较大的树。

  • 前序、中序、后序遍历:适用于二叉树的不同遍历顺序。

根据具体需求选择合适的遍历方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值