简体   繁体   English

Javascript:二叉搜索树顺序遍历递归混淆

[英]Javascript: Binary Search Tree in order traversal recursive confusion

given the code below, I am bit confused as to how the order of operations happens to get an in order traversal of a binary search tree.鉴于下面的代码,我对操作顺序如何碰巧获得二叉搜索树的顺序遍历感到有些困惑。

BinarySearchTree.prototype.inOrder = function() {
    if (this.root == null) {
      return null;
    } else {
      var result = new Array();
      function traverseInOrder(node) {       
        node.left && traverseInOrder(node.left);
        result.push(node.data);
        node.right && traverseInOrder(node.right);
      }
      traverseInOrder(this.root);
      return result;
    };
}

I tried to add a debugger statement and follow but I get lost inside:我试图添加一个调试器语句并遵循,但我迷失在里面:

  function traverseInOrder(node) {       
    node.left && traverseInOrder(node.left); //step 1
    result.push(node.data);  //step 2
    node.right && traverseInOrder(node.right); //step 3
  }

node.left && traverseInOrder(node.left); (Step 1) gets run then gets run again then gets run again. (步骤 1)运行,然后再次运行,然后再次运行。 Finally when there is no node.left , Step 2 gets called: result.push(node.data);最后,当没有node.left时,调用第 2 步: result.push(node.data);
This is the part where it loses me .这是它失去我的部分 Now it tries to run node.right && traverseInOrder(node.right) but there is no node.right but instead of moving out of the function, it goes back up to Step 2, result.push(node.data);现在它尝试运行node.right && traverseInOrder(node.right)但没有node.right而是没有移出 function,而是返回到步骤 2, result.push(node.data); . .

Is this queued up from the multiple recursive calls in Step 1?这是从步骤 1 中的多个递归调用中排队的吗?

Let's look at an example.让我们看一个例子。 Let it be the below tree which will be traversed in order .让它成为将按in order遍历的下面的树。

在此处输入图像描述

  • The first traverseInOrder is called with this.root , it means the parameter from the above example is A .第一个traverseInOrder是用this.root调用的,这意味着上例中的参数是A The node.left exists, it follows traverseInOrder is called with parameter B . node.left存在,它遵循traverseInOrder调用参数B
    • In the call of B the node.left exists, it follows traverseInOrder is called with parameter D .B的调用中node.left存在,它遵循traverseInOrder被调用参数D
      • In the call of D node.left does not exist ( node.left is falsy), so result.push(node.data);D的调用中node.left不存在( node.left是假的),所以result.push(node.data); is called with parameter D .使用参数D调用。 In the next step node.right is falsy, it follows the traversInOrder with parameter D is finished.在下一步中, node.right是假的,它遵循带有参数DtraversInOrder完成。 We get back to the B .我们回到B
    • We are back to call B , and because the traversInOrder with D just finished, result.push(node.data) will be called with parameter B .我们返回调用B ,因为带有DtraversInOrder刚刚完成, result.push(node.data)将使用参数B调用。 And as next node.right is truthy so traverseInOrder is called with the node.right so with E .并且由于下一个node.right是真实的,因此使用node.right调用traverseInOrder ,因此使用E调用。
      • At E node.left is falsy, result.push is called with parameter E .E node.left是假的, result.push使用参数E调用。 node.right is falsy is the call with E ended here. node.right是 falsy 是与E的通话在这里结束。 We get back to call A , because as we return from here to the call of B it finishes at this point.我们回到调用A ,因为当我们从这里返回到调用B时,它在这一点上完成。
  • At call with parameter A we just finished the left node, result.push(node.data);在使用参数A调用时,我们刚刚完成了左侧节点result.push(node.data); is called for A and next node.right is truthy so result.push(node.data) is called with the right node witch means parameter C .A调用并且下一个node.right是真实的,因此使用右节点调用result.push(node.data)意味着参数C

And it goes on the same with the C,F,G. C,F,G 也是如此。

tenkmilan already did an excellent job of showing how to envision that code. tenkmilan 已经出色地展示了如何构想该代码。

Here I go a different path, and write a simpler inorder traversal.这里我go路径不同,写一个更简单的中inorder遍历。 It should be fairly clear how that can map to the code supplied.应该很清楚 map 提供的代码如何。

An inorder traversal is simple enough.inorder遍历很简单。 preorder and postorder are the other most common tree traversals and they work on arbitrary finite trees. preorderpostorder是其他最常见的树遍历,它们适用于任意有限树。 Inorder is only defined for binary trees, and uses the left - and right -children of your node. right left节点。 The traversal order is to (recursively) traverse the left child, then visit the node itself, and finally to (recursively) traverse the right child.遍历顺序是(递归)遍历左孩子,然后访问节点本身,最后(递归)遍历右孩子。

We can write such a traversal simply:我们可以简单地编写这样的遍历:

const inorder = (tree) =>
  tree 
    ? [
        ... inorder (tree .left),
        tree .data,
        ... inorder (tree .right)
      ]
    : []

We have a base-case where the node we're looking at is empty, and we just return an empty array.我们有一个基本情况,我们正在查看的节点是空的,我们只返回一个空数组。 In the general case we just concatenate together a recursive call on left.tree with our current node's value and a recursive call on right.tree .在一般情况下,我们只是将left.tree上的递归调用与当前节点的值和right.tree上的递归调用连接在一起。

That's all there is to inorder traversal.这就是中inorder遍历的全部内容。 You can see it in action in this snippet:您可以在此代码段中看到它的实际效果:

 const inorder = (tree) => tree? [... inorder (tree.left), tree.data, ... inorder (tree.right) ]: [] const tree = { data: 'F', left: { data: 'B', left: {data: 'A'}, right: { data: 'D', left: {data: 'C'}, right: {data: 'E'} } }, right: { data: 'H', left: {data: 'G'}, right: {data: 'I'} } } console.log (inorder (tree))

Of course, this is for a simple tree stored as a plain JS object.当然,这是针对存储为普通 JS object 的简单树。 But mapping back your sample code is easy enough.但是映射回您的示例代码很容易。 I'm guessing that if you can follow this one, you can quickly follow that one.我猜如果你能关注这个,你就可以快速关注那个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 Javascript 上显示二叉搜索树遍历(递归方式) - Display Binary Search Tree Traversal on Javascript (Recursive way) 在 JavaScript 中递归二叉搜索树遍历结束时返回一个值 - Returning a value at the end of a recursive binary search tree traversal in JavaScript 使用 Javascript 的二叉树级顺序遍历 - Binary Tree Level Order Traversal using Javascript JavaScript二进制搜索树按顺序遍历返回undefined作为答案的一部分 - JavaScript Binary Search Tree in-order traversal returning undefined as part of answer Javascript-按顺序遍历二叉树。 上一个值正在打印未定义 - Javascript - Binary tree traversal in order. Last value is printing undefined 尝试返回二叉树的级别顺序遍历 - Trying to return a level order traversal of a binary tree 二叉搜索树遍历 - 查找最接近的值 - Binary Search Tree traversal - Find Closest Value 为JavaScript二进制搜索树编写递归添加方法 - Writing a recursive add method for a Javascript Binary Search Tree JavaScript:使用Generator制作二叉搜索树In order Iterator - JavaScript: using Generator to make Binary Search Tree In order Iterator 递归邮政订单树遍历而不创建新节点 - Recursive post order tree traversal without creating new nodes
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM