二叉树-深度优先遍历

时间:2018-07-31 17:07:43

标签: javascript binary-tree depth-first-search

我想对该二叉树进行深度优先遍历:

SELECT s.StockItemName, s.StockLevel, sc.StockLevel
FROM stock s
LEFT JOIN stock_copy sc ON sc.Id = s.Id AND sc.StockLevel <> s.StockLevel
ORDER BY s.StockItemName

这是节点结构:

          1
         / \
        4   5
       / \   \
      4   4   5

访问功能(仅用于打印节点数据):

function TreeNode(data){
    this.data = data
    this.left = this.right = []

    this.addLeft = function(node){
        this.left.push(node)
    }

    this.addRight = function(node){
        this.right.push(node)
    }
}

遍历功能:

function visit(node){
    console.log(node.data)
}

添加二叉树结构:

function traverse(node){
   if(node === null) return

   visit(node)

   //visit left branch
   for(node of node.left) traverse(node)

   //visit right branch
   for(node of node.right) traverse(node)
}

输出:

let rootNode = new TreeNode(1)
let node_4A = new TreeNode(4)
let node_4B = new TreeNode(4)
let node_4C = new TreeNode(4)
let node_5A = new TreeNode(5)
let node_5B = new TreeNode(5)

//add root node branches
rootNode.addLeft(node_4A)
rootNode.addRight(node_5A)

node_4A.addLeft(node_4B)
node_4A.addRight(node_4C)
node_5A.addRight(node_5B)

因此它可以正确打印出节点数据,但是总是有另一个最右边的节点被打印了两次(即最后一个1 4 4 4 5 5 5 )。你知道为什么会发生吗?

我对Javascript调用栈不太熟悉,但是原因可能是我正在递归函数中运行2个5循环吗?

谢谢。

3 个答案:

答案 0 :(得分:2)

您对左右对象使用相同的对象引用。

this.left = this.right = []

您需要独立的数组:

this.left = [];
this.right = [];

要获取正确的节点,请使用与node不同的名称进行迭代。

function traverse(node) {
    if (!node) return;  // you never have a value of null for a node
    visit(node)

    //visit left branch
    for (let n of node.left) {
        traverse(n);
    }
    //visit right branch
    for (let n of node.right) {
        traverse(n);
    }
}

function TreeNode(data) {
    this.data = data
    this.left = [];
    this.right = [];

    this.addLeft = function (node) {
        this.left.push(node)
    }

    this.addRight = function (node) {
        this.right.push(node)
    }
}

function visit(node) {
    console.log(node.data)
}

function traverse(node) {
    if (!node) return; // you never have a value of null for a node

    visit(node)

    for (let n of node.left) {
        traverse(n);
    }

    for (let n of node.right) {
        traverse(n);
    }
}

let rootNode = new TreeNode(1)
let node_4A = new TreeNode(4)
let node_4B = new TreeNode(4)
let node_4C = new TreeNode(4)
let node_5A = new TreeNode(5)
let node_5B = new TreeNode(5)

//add root node branches
rootNode.addLeft(node_4A)
rootNode.addRight(node_5A)

node_4A.addLeft(node_4B)
node_4A.addRight(node_4C)
node_5A.addRight(node_5B)
traverse(rootNode);

答案 1 :(得分:0)

您这样做:

 this.left = this.right = []

因此,左边的叶子实际上与右边的叶子相同。您想要:

 this.left = [];
 this.right = [];

只是为了好玩:对于生成器来说,这实际上是一个很好的用例:

 TreeNode.prototype.leftFirst = function*() {
    yield this.data;
    for(const child of this.left.concat(this.right))
       yield* child.leftFirst();
 };

因此您可以这样做:

 for(const node of tree.leftFirst())
    console.log(node);

答案 2 :(得分:0)

DFS(深度优先搜索)通常很容易使用递归实现。用js语言引用此函数定义-

    const recFnc = (currNode) => {
      if (currNode !== null) {
        if (currNode.lNode !== null) {
          recFnc(currNode.lNode, lPath);
        }
        if (currNode.rNode !== null) {
          recFnc(currNode.rNode, rPath);
        }
      }
    };

    recFnc(rootNode);

请参阅我创建的此类-https://www.npmjs.com/package/@dsinjs/binary-tree 并参阅此功能文档,该文档处理路径计算等内容-https://dsinjs.github.io/binary-tree/#find