简体   繁体   English

广度优先搜索二进制搜索树javascript实现

[英]Breadth first search binary search tree javascript implementation

I have the following code that implements a BST tree in JavaScript. 我有以下代码在JavaScript中实现BST树。

function Node(value) {
  this.left = null;
  this.right = null;
  this.value = value;
}

function BinarySearchTree() {
  this.root = null;
  return;
}

BinarySearchTree.prototype.push = function(value) {

  if (!this.root) {
    this.root = new Node(value);
    return;
  }

  var currentRoot = this.root;
  var newNode = new Node(value);
  while (currentRoot) {
    if (value < currentRoot.value) {
      if (!currentRoot.left) {
        currentRoot.left = newNode;
        break;
      } else {
        currentRoot = currentRoot.left;
      }
    } else {

      if (!currentRoot.right) {
        currentRoot.right = newNode;
        break;
      } else {
        currentRoot = currentRoot.right;
      }

    }

  }

}

var a = new BinarySearchTree();
a.push(27);
a.push(14);
a.push(35);
a.push(10);
a.push(19);
a.push(31);
a.push(42);

I am trying to implement a function which can do a breadth first traversal of the tree. 我正在尝试实现一个可以对树进行广度优先遍历的函数。 This is what I have tried so far. 到目前为止,这是我尝试过的。

console.log(a.root.value);
traverse(a.root);

//function to traverse 
function traverse(node) {

  currentNode = node;
  while (currentNode.left) {
    displayNodes(currentNode);
    parent = currentNode;
    currentNode = currentNode.left;
    displayNodes(currentNode);
    if(parent.right!=null){
    displayNodes(parent.right);
    }
  }
}

//function that displays the left and right node of a node 
function displayNodes(node) {


  if (node.left != null) {
    console.log(node.left.value);
  }
  if (node.right != null) {
    console.log(node.right.value);
  }
}

I am unable to implement a function that could scale with a large number of data. 我无法实现可以扩展大量数据的功能。 I am not sure if a recursive method to traverse would be better or using a while loop. 我不确定递归遍历方法会更好还是使用while循环。 How can I implement the function? 如何实现该功能? I know that the function gives unexpected behavior? 我知道函数会产生意外行为吗? What correction should I make? 我该怎么做?

You currently traverse the path from the root node to the left-most leaf. 您当前正在遍历从根节点到最左边的叶子的路径。

A simple non-recursive breadth-first traversal function invoking a callback on each traversed node could look as follows: 一个简单的非递归广度优先遍历函数可以在每个被遍历的节点上调用回调:

// Breadth-first traversal:
function traverse(node, cb) {
  var current = [node];
  while (current.length > 0) {
    var next = [];
    for (var node of current) {
      cb(node);
      if (node.left) next.push(node.left);
      if (node.right) next.push(node.right);
    }
    current = next;
  }
}

// Example:
traverse(root, function(node) {
  console.log(node.value);
});

It works by keeping an array of already discovered or traversed nodes current which initially contains just your root node. 它通过保持已发现的或经过的各个节点的阵列current最初仅包含你的根节点。 Now, you iteratively replace each node in that list with its children. 现在,您用其子节点迭代替换该列表中的每个节点。 In above function, the children are stored in a next array. 在上面的函数中,子级存储next数组中。 At the end of each iteration, all nodes of the current level in current are replaced with all their children of the next deeper level in next . 在每次迭代结束,在当前级别的所有节点的current将替换所有的在未来更深层次的孩子next See also the first suggestion given by @DavidKnipe's answer . 另请参阅@DavidKnipe的答案给出的第一个建议。

A non-recursive approach has the advantage of not being subject to the call stack size limit. 非递归方法的优点是不受调用堆栈大小限制。 This theoretically allows you to handle larger data structures when the call stack size is limited . 从理论上讲,当调用堆栈大小受到限制时,您可以处理较大的数据结构。

If you're looking for a way to BFS using O(1) memory, I don't think there's a nice way to do it. 如果您正在寻找使用O(1)内存进行BFS的方法,我认为没有一种很好的方法可以做到这一点。 (DFS is another matter though. Are you sure it has to be BFS?) (不过,DFS是另一回事。确定要使用BFS吗?)

There are two ways I can see to do this. 我可以通过两种方法来做到这一点。 You could start with the array [this.root] , and write a function that iterates over an array of nodes and then returns an array of children of those nodes. 您可以从数组[this.root] ,然后编写一个函数,该函数在节点数组上进行迭代,然后返回这些节点的子[this.root]组。 Then call that function on the array of children, and keep going down the tree until you get an empty array. 然后在子数组上调用该函数,并继续往下走直到得到一个空数组。

If memory is an issue, there's another way to do it. 如果内存是一个问题,那么还有另一种方法。 Instead of remembering the array of nodes at a given level, you could just remember the depth, then redo the iteration each time. 您不必记住给定级别的节点数组,而只需记住深度,然后每次都重做迭代即可。 So you'd have a function which takes a natural number n and iterates over the tree, but without going deeper than n , and does whatever it is you're trying to do at the n th level only; 因此,您将拥有一个函数,该函数采用自然数n并遍历树,但不深于n ,并且仅在第n层做您想做的事情; then call this function for all values of n until there are no more nodes left. 然后对所有n值调用此函数,直到没有剩余的节点为止。

That last one might sound very wasteful, but it might not be too bad if the last few levels of the tree contain most of the nodes. 最后一个听起来可能很浪费,但是如果树的最后几个级别包含大多数节点,那可能还不错。 It depends on your dataset and computational capabilities. 这取决于您的数据集和计算能力。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM