C# 二叉搜索树的迭代高度

C# 二叉搜索树的迭代高度,c#,algorithm,binary-tree,binary-search-tree,breadth-first-search,C#,Algorithm,Binary Tree,Binary Search Tree,Breadth First Search,我尝试了一种迭代方法来寻找二叉搜索树的高度/深度。 基本上,我尝试使用广度优先搜索来计算深度,使用队列来存储树节点,只使用整数来保存树的当前深度。树中的每个节点都排队,并检查其子节点。如果存在子节点,则增加深度变量。代码如下: public void calcDepthIterative() { Queue<TreeNode> nodeQ = new LinkedList<TreeNode>(); TreeNode node = root; int

我尝试了一种迭代方法来寻找二叉搜索树的高度/深度。 基本上,我尝试使用广度优先搜索来计算深度,使用队列来存储树节点,只使用整数来保存树的当前深度。树中的每个节点都排队,并检查其子节点。如果存在子节点,则增加深度变量。代码如下:

public void calcDepthIterative() {
    Queue<TreeNode> nodeQ = new LinkedList<TreeNode>();
    TreeNode node = root;
    int level = 0;
    boolean flag = false;

    nodeQ.add(node);
    while(!nodeQ.isEmpty()) {
        node = nodeQ.remove();
        flag = false;
        if(node.leftChild != null) {
            nodeQ.add(node.leftChild);
            flag = true;
        }

        if(node.rightChild != null) {
            nodeQ.add(node.rightChild);
            flag = true;
        }
        if(flag) level++;
    }
    System.out.println(level);

}
它将深度显示为3,而不是2。 我做了另一个版本,使用一个额外的队列来存储当前深度,使用中的思想。我想避免使用额外的队列,所以我尝试优化它。下面是可以工作的代码,尽管使用了一个额外的队列

public void calcDepthIterativeQueue() {
    Queue<TreeNode> nodeQ = new LinkedList<TreeNode>();
    Queue<Integer> lenQ = new LinkedList<Integer>();

    TreeNode node = root;
    nodeQ.add(node);
    lenQ.add(0);
    int maxLen = 0;
    while(!nodeQ.isEmpty()) {
        TreeNode curr = nodeQ.remove();
        int currLen = lenQ.remove();
        if(curr.leftChild != null) {
            nodeQ.add(curr.leftChild);
            lenQ.add(currLen + 1);
        }

        if(curr.rightChild != null) {
            nodeQ.add(curr.rightChild);
            lenQ.add(currLen + 1);
        }
        maxLen = currLen > maxLen ? currLen : maxLen;
    }
    System.out.println(maxLen);

}
问题:

有没有办法修复第一个方法,使其返回正确的深度

编辑 见下面接受的答案

rici答案的Java代码:


这里有一种方法:

Create a Queue, and push the root onto it.
Let Depth = 0
Loop:
    Let NodeCount = size(Queue)
    If NodeCount is 0:
        return Depth.
    Increment Depth.
    While NodeCount > 0:
        Remove the node at the front of the queue.
        Push its children, if any, on the back of the queue
        Decrement NodeCount.
工作原理
每次设置NodeCount时,扫描即将开始一个新行。NodeCount设置为该行中的节点数。当所有这些节点都已删除(即NodeCount减为零)时,该行已完成,且该行上节点的所有子节点已添加到队列中,因此队列再次具有完整的行,并且NodeCount再次设置为该行中的节点数。

以下是一种方法:

Create a Queue, and push the root onto it.
Let Depth = 0
Loop:
    Let NodeCount = size(Queue)
    If NodeCount is 0:
        return Depth.
    Increment Depth.
    While NodeCount > 0:
        Remove the node at the front of the queue.
        Push its children, if any, on the back of the queue
        Decrement NodeCount.
工作原理 每次设置NodeCount时,扫描即将开始一个新行。NodeCount设置为该行中的节点数。当所有这些节点都被删除时,即NodeCount减为零,则该行已完成,并且该行上节点的所有子节点都已添加到队列中,因此该队列再次具有完整的行,并且NodeCount再次设置为该行中的节点数。

是否重复

int Depth(Node node)
{
    int depthR=0,depthL=0;
    if(Right!=null)depthR=Depth(Right);
    if(Left!=null)depthL=Depth(Left);
    return Max(depthR,depthL)+1;
}
如果你想要一个从零开始的深度,只需将得到的深度减去1即可。

重复怎么样

int Depth(Node node)
{
    int depthR=0,depthL=0;
    if(Right!=null)depthR=Depth(Right);
    if(Left!=null)depthL=Depth(Left);
    return Max(depthR,depthL)+1;
}
public int height(Node root){
  int ht =0;
  if(root==null) return ht;
  Queue<Node> q = new ArrayDeque<Node>();
  q.addLast(root);
  while(true){
      int nodeCount = q.size();
      if(nodeCount==0) return ht;
      ht++;
      while(nodeCount>0){
       Node node = q.pop();
       if(node.left!=null) q.addLast(node.left);
       if(node.right!=null) q.addLast(node.right);
       nodeCount--;
      }
 }

如果你想要一个从零开始的深度,只需将结果深度减去1。

我不完全是正数,但我假设你计算的是子树的累积深度,而不是子树的最大深度,因为您可能会在每个子树中增加计数器变量,而不是在每个级别增加一次。第一种方法是计算具有子节点的节点数,它可以相对于最大树深度以几何方式增长。它似乎存在根本性的缺陷。我不是完全肯定,但我假设您计算的是子树的累积深度,而不是子树的最大深度,因为您可能会增加每个子树中的计数器变量,而不是每个级别一次。第一种方法是计算具有子节点的节点数,它可以相对于最大树深度进行几何增长。它似乎有根本性的缺陷。它不能为只有一个节点的树返回正确答案。@chasefornone:为什么不?开始时,将一个节点推送到队列上,其大小为1,这将是NodeCount的第一个值。深度增加到1,while循环弹出单个节点,不推任何内容。然后在下一个循环中,返回深度1。@rici:抱歉我的错误,非常棒的解决方案。对于只有一个节点的树,它不能返回正确的答案。@chasefornone:为什么不能?开始时,将一个节点推送到队列上,其大小为1,这将是NodeCount的第一个值。深度增加到1,while循环弹出单个节点,不推任何内容。然后在下一个循环中,返回深度1。@rici:抱歉我的错误,非常棒的解决方案。他正在讨论一种迭代方法,而不是递归方法。1。不是迭代的。2.与此相比,我认为递归有一个更简洁的版本。他讨论的是迭代方法,而不是递归。1。不是迭代的。2.与此相比,我认为递归有一个更干净的版本。
public int height(Node root){
  int ht =0;
  if(root==null) return ht;
  Queue<Node> q = new ArrayDeque<Node>();
  q.addLast(root);
  while(true){
      int nodeCount = q.size();
      if(nodeCount==0) return ht;
      ht++;
      while(nodeCount>0){
       Node node = q.pop();
       if(node.left!=null) q.addLast(node.left);
       if(node.right!=null) q.addLast(node.right);
       nodeCount--;
      }
 }