【问题标题】:How to find height of BST iteratively?如何迭代地找到 BST 的高度?
【发布时间】:2012-01-13 10:11:31
【问题描述】:
  public void HeightIterative()
    {
        int counter = 0;
        int counter2 = 0;
        TreeNode current=root;

        if(current != null)
        {
            while(current.LeftNode!=null)
            {
                counter++;
                current = current.LeftNode;
            }
            while(current.RightNode!=null)
            {
                counter2++;
                current = current.RightNode;
            }
        }

        int res = 1+Math.Max(counter, counter2);
        Console.WriteLine("The Height Of Tree Is: "+res);
    }

我写了迭代方法,计算树的高度。但在某些情况下,它无法正常工作。以防万一: 10 1 2 3 4 5 18 17 16 15 14 13 有什么问题。根据此序列树的高度为 6,而我的代码显示为 5。

【问题讨论】:

  • 必须是迭代的、BST、BFS....作业?
  • 不是作业!如果是,那么我使用作业标签提到它
  • 那你为什么坚持使用迭代而不是递归呢?
  • 如果你有一个包含 100000 个元素的文本文件并且你想将它存储在二叉树中。然后想知道树的高度。如果您递归执行此操作,则会发生 stackoverflow 异常。这就是原因
  • 平衡二叉树中的 100000 个元素是 log(100000)/log(2) ~ 20 次递归调用。没有堆栈溢出异常的可能性。

标签: c# visual-studio-2010 binary-tree binary-search-tree


【解决方案1】:

问题:

您在第一个循环中找到最左侧节点的深度,在第二个循环中找到最右侧节点的深度,并且永远不会询问任何涉及到左和右的节点。

解决方案:

有一个循环向下钻取左侧节点,但将它“跳过”的每个右侧节点添加到队列中。当您用完左侧节点时,从队列中弹出一个节点并继续直到队列变空。您需要将放入队列中的每个节点的高度与该节点一起存储。

【讨论】:

  • 不像描述的那样,因为你总是走左孩子。但如果队列是 FILO(即堆栈),则它唯一的深度优先;如果队列是 FIFO,那么你会得到介于两者之间的东西。
【解决方案2】:

您正在使用两个循环,但每个循环仅调查节点的一侧,但树中的每个节点都有两侧,您应该全部调查。你可以通过递归调用来做到这一点。

private int GetLen(TreeNode node)
{
  var result = 0;

  if(node != null)
  {
    result = Math.Max(GetLen(node.LeftNode), GetLen(node.RightNode)) + 1;
  }

  return result;
}

public void HeightIterative()
{
  int res = GetLen(root);
  Console.WriteLine("The Height Of Tree Is: "+res);
}

迭代版本:

private class NodeInfo
{
  public NodeInfo(TreeNode node, int len)
  {
    Node = node;
    Len = len;
  }

  public TreeNode Node {get; private set;}
  public int Len {get; private set;}
}

public void HeightIterative()
{
    int maxLen = 0;

    var queue = new Queue<NodeInfo>();
    queue.Enqueue(new NodeInfo(root, 1));

    while (queue.Count > 0)
    {
        var item = queue.Dequeue();
        var current = item.Node;
        var currentLen = item.Len;

        if (current.LeftNode != null)
        {
            queue.Enqueue(new NodeInfo(current.LeftNode, currentLen + 1));
        }

        if (current.RightNode != null)
        {
            queue.Enqueue(new NodeInfo(current.RightNode, currentLen + 1));
        }

        if (currentLen > maxLen)
        {
            maxLen = currentLen;
        }
    }

    Console.WriteLine("The Height Of Tree Is: " + maxLen);
}

【讨论】:

  • 老兄,我提到我需要迭代版本。
  • 我不知道如何实现它:) 理解起来会很复杂。但我会尝试:)
  • TreeNode 有 Parent 属性吗?
  • 可以查看迭代版本
  • 只是一个用于两个或多个值的简单容器。它从 DN 4.0 引入,如果您使用以前的 DN 版本,您可以创建自己的类或使用 KayValuePair
【解决方案3】:

有一种方法不需要任何额外的空间,除了用于存储节点的队列。

  1. 添加当前元素的子节点并记住队列的大小。
  2. 让每个出队调用递减计数器
  3. 当计数器达到零时,这意味着我们完成了当前级别。
  4. 重复并计数计数器达到零的次数 - 这是树的深度/高度

代码如下:

public int treeDepth(Node root){
    int height = 0;
    int counterNodesInLevel = 1;

    if(root!=null)
    {
        Queue<Node> queue=new Queue<Node>()
        queue.enqueue(root);

        while (!queue.isEmpty()){
            Node current = queue.dequeue();
            counterNodesInLevel -= 1;

            if(current.left!=null){
               queue.enqueue(current.left)
            }

            if(current.right!=null){
               queue.enqueue(current.right)
            }

            if (counterNodesInLevel == 0){
                height += 1;
                counterNodesInLevel = queue.Size();
            }                    
        }    
    }    
    return height;
}    

时间复杂度为O(N),空间复杂度为O(N)

【讨论】:

  • if 语句中的 dequeue 应该是 enqueue。我提交了一个编辑(还更改了一些变量名称以使其更清晰)。除此之外:很好的答案!
【解决方案4】:
public int Height()
    {
        int result = GetMaxHeight(this.Root,0);
        return result;
    }

    private int GetMaxHeight(Node<T> node,int count)
    {
        int leftMax = 0, rightMax = 0;
        if (node.Left != null)
        {
            leftMax = GetMaxHeight(node.Left, count+1);
        }
        if (node.Right != null)
        {
            rightMax = GetMaxHeight(node.Right, count + 1);
        }

        if(node.Left==null && node.Right == null)
        {
            return count;
        }

        return Math.Max(leftMax,rightMax);
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-30
    • 2013-11-26
    • 2016-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多