簡體   English   中英

二叉樹廣度優先搜索算法

[英]Binary tree breadth first search algorithm

在二叉樹 BFS 算法中,有人可以幫助我理解為什么我們在下面的代碼中做一個height - 1 我寫了這段代碼,但直到我在網上發現你需要做一個高度 - 1 之前它才起作用。

public class BreadthFirstSearch {

public static int calculateHeightOfTree(Node root) {
    if (root == null) {
        return 0;
    } else {
        return 1 + Math.max(calculateHeightOfTree(root.leftNode), calculateHeightOfTree(root.rightNode));
    }
}

public static void printDataAtAllLevels(Node root, int height) {
    for (int i = 1; i <= height; i++) {
        printDataAtGivenLevel(root, i);
    }
}

public static void printDataAtGivenLevel(Node root, int height) {
    if (root == null) {
        return;
    }
    if (height == 1) {
        System.out.println(root.data);
    } else {
        printDataAtGivenLevel(root.leftNode, height - 1);
        printDataAtGivenLevel(root.rightNode, height - 1);
    }
}

public static void main(String[] args) {
    Node node = new Node(1);
    node.leftNode = new Node(2);
    node.rightNode = new Node(3);
    node.leftNode.leftNode = new Node(4);
    node.leftNode.rightNode = new Node(5);

    System.out.println("Level order traversal of binary tree is ");
    int height = calculateHeightOfTree(node);
    System.out.println("HEIGHT: " + height);
    printDataAtAllLevels(node, height);
}

那么,如果要打印樹的n級數據,就相當於打印了左右子樹的n-1級數據。 因此,當您將左右子樹傳遞給遞歸調用時,您應該請求打印級別減少 1 的數據。

例如,由於樹的根為 1 級,因此根的左右子節點為 2 級,所以如果要打印原始樹的所有 2 級數據,就相當於打印了該級的數據1 為左右子樹。

如果您不減少height則在每個(遞歸)方法調用中它始終是相同的值。

因此遞歸不會停止,因為height == 1總是假的。 它只會因為root == null為真而停止,因為您到達了子樹的末尾。 但在這種情況下,將沒有輸出,而只有return

因為高度 int printDataAtGivenLevel(Node root, int height)是相對於根的高度。 所以如果你想從root打印 level 2,你需要從root.leftroot.right打印 level 1。

這樣您就可以打印從高度最低的節點開始到高度最大的節點的高度。

老實說,當我閱讀二叉樹廣度優先搜索算法時,我並沒有考慮一系列深度限制的DFS遍歷,而是訪問給定級別的節點,並收集下一級的節點,沖洗並重復:

static void doStuff(Node root){
  List<Node> current=new ArrayList<>();
  current.add(root);
  int level=0;
  int total=0;
  while(current.size()>0){
    level++;
    System.out.println("Level "+level+":");
    List<Node> next=new ArrayList<>();
    for(int i=0;i<current.size();i++){
      Node node=current.get(i);
      System.out.print(node.data+" ");
      if(node.leftNode!=null)
        next.add(node.leftNode);
      if(node.rightNode!=null)
        next.add(node.rightNode);
      total++;
    }
    System.out.println();
    current=next;
  }
  System.out.println(total+" nodes visited, from "+level+" levels");
}

然后它可以被欺騙到一個列表中:

static void doStuff(Node root){
  List<Node> nodes=new LinkedList<>();
  nodes.add(root);
  int level=0;
  int total=0;
  int current;
  while((current=nodes.size())>0){
    level++;
    System.out.println("Level "+level+":");
    while(current-->0){
      Node node=nodes.removeFirst();
      System.out.print(node.data+" ");
      if(node.leftNode!=null)
        nodes.add(node.leftNode);
      if(node.rightNode!=null)
        nodes.add(node.rightNode);
      total++;
    }
    System.out.println();
  }
  System.out.println(total+" nodes visited, from "+level+" levels");
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM