【问题标题】:Height of binary search tree iteratively迭代二叉搜索树的高度
【发布时间】:2013-02-07 11:13:03
【问题描述】:

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

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

}

但是,代码并不适用于所有情况。例如,对于以下树:

     10
   /    \
  4      18
   \    /  \
    5  17   19

它将深度显示为 3,而不是 2。 我使用this page 中的想法使用附加队列来存储当前深度做了它的替代版本。我想避免使用额外的队列,所以我尝试优化它。这是有效的代码,尽管使用了额外的队列。

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 代码:

public void calcDepthIterative() {
    Queue<TreeNode> nodeQ = new LinkedList<TreeNode>();
    int depth = 0;
    nodeQ.add(root);
    while(!nodeQ.isEmpty()) {
        int nodeCount = nodeQ.size();
        if(nodeCount == 0)
            break;
        depth++;
        while(nodeCount > 0) {
            TreeNode topNode = nodeQ.remove();
            if(topNode.leftChild != null)
                nodeQ.add(topNode.leftChild);
            if(topNode.rightChild != null)
                nodeQ.add(topNode.rightChild);
            nodeCount--;
        }
    }
    System.out.println(depth);
}

【问题讨论】:

  • 我并不完全肯定,但我假设您正在计算子树的累积深度,而不是子树的最大深度,因为您可能会增加每个子树中的计数器变量而不是每个子树一次水平。
  • 第一种方法是计算有子节点的数量,它可以相对于最大树深度呈几何增长。它似乎存在根本缺陷。

标签: c# algorithm binary-tree binary-search-tree breadth-first-search


【解决方案1】:

这是一种方法:

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 再次设置为该行中的节点数。

【讨论】:

  • 它不能为只有一个节点的树返回正确的答案。
  • @chasefornone:为什么不呢?一开始,您将一个节点推入队列,其大小为 1,这将是 NodeCount 的第一个值。深度增加为 1,while 循环弹出单个节点,不推送任何内容。然后在下一个循环中,返回深度(1)。
  • @rici: 抱歉我的错误,很棒的解决方案。
【解决方案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--;
      }
 }

【讨论】:

    【解决方案3】:

    递归怎么样,

    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。

    【讨论】:

    • 他正在讨论一种迭代方法,而不是递归。
    • 1.不是迭代的。 2. 与此相比,我认为有一个更简洁的递归版本。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-19
    • 2013-11-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多