繁体   English   中英

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

[英]Breadth first search binary search tree javascript implementation

我有以下代码在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);

我正在尝试实现一个可以对树进行广度优先遍历的函数。 到目前为止,这是我尝试过的。

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);
  }
}

我无法实现可以扩展大量数据的功能。 我不确定递归遍历方法会更好还是使用while循环。 如何实现该功能? 我知道函数会产生意外行为吗? 我该怎么做?

您当前正在遍历从根节点到最左边的叶子的路径。

一个简单的非递归广度优先遍历函数可以在每个被遍历的节点上调用回调:

// 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);
});

它通过保持已发现的或经过的各个节点的阵列current最初仅包含你的根节点。 现在,您用其子节点迭代替换该列表中的每个节点。 在上面的函数中,子级存储next数组中。 在每次迭代结束,在当前级别的所有节点的current将替换所有的在未来更深层次的孩子next 另请参阅@DavidKnipe的答案给出的第一个建议。

非递归方法的优点是不受调用堆栈大小限制。 从理论上讲,当调用堆栈大小受到限制时,您可以处理较大的数据结构。

如果您正在寻找使用O(1)内存进行BFS的方法,我认为没有一种很好的方法可以做到这一点。 (不过,DFS是另一回事。确定要使用BFS吗?)

我可以通过两种方法来做到这一点。 您可以从数组[this.root] ,然后编写一个函数,该函数在节点数组上进行迭代,然后返回这些节点的子[this.root]组。 然后在子数组上调用该函数,并继续往下走直到得到一个空数组。

如果内存是一个问题,那么还有另一种方法。 您不必记住给定级别的节点数组,而只需记住深度,然后每次都重做迭代即可。 因此,您将拥有一个函数,该函数采用自然数n并遍历树,但不深于n ,并且仅在第n层做您想做的事情; 然后对所有n值调用此函数,直到没有剩余的节点为止。

最后一个听起来可能很浪费,但是如果树的最后几个级别包含大多数节点,那可能还不错。 这取决于您的数据集和计算能力。

暂无
暂无

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

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