簡體   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