【问题标题】:AVL tree balance factorAVL 树平衡因子
【发布时间】:2014-01-29 14:27:38
【问题描述】:

我有一个 AVL 树类,我想找到每个节点的平衡因子(balance_factor: node->Left_child->height - node->right_Child->height

这是我的代码:

int tree::findBalanceFactor(node p){
    int a;
    if( p.lchild)   p.lchild->balance_factor=findBalanceFactor( *p.lchild );    
    if( p.rchild)   p.rchild->balance_factor=findBalanceFactor( *p.rchild );

    if( p.rchild && p.lchild )          a=p.balance_factor = p.lchild->height - p.rchild->height ;
    if( p.rchild && !p.lchild )         a=p.balance_factor = 0 - p.rchild->height;
    if( !p.rchild && p.lchild )         a=p.balance_factor = p.lchild->height;
    if( !p.rchild && !p.lchild )        a=p.balance_factor = 0;

    cout << "md" << a << endl;
    return a;
}

在主函数中,当我打印 root-&gt;balance_factor 时,它总是显示数字为零 balance_factor 是一个公共变量,在构造函数中我将其分配为零。

我的代码有什么问题?

【问题讨论】:

    标签: c++ recursion tree avl-tree


    【解决方案1】:

    有一个比测试 lchild 和 rchild 的每个排列更简单的方法

    int tree::findBalanceFactor(node &n) {
        int lheight = 0; 
        int rheight = 0;
    
        if (n.lchild) {
            findBalanceFactor(*n.lchild);
            lheight = n.lchild->height;
        }
        if (n.rchild) {
            findBalanceFactor(*n.rchild);
            rheight = n.rchild->height;
        }
        n.balance_factor = lheight - rheight;
        std::cout << "md " << n.balance_factor << std::endl;
        return n.balance_factor;
    }
    

    由于这似乎最终成为了一个全代码答案,所以我将添加一个简短的注释,说明如何从原始代码到此。

    在一个层面上,很容易观察到原始中的四个分支中的每一个都具有相同的形式 (left - right),但只要 lchild 为空,left=0 就具有 right=0,只要 rchild 为空.

    更广泛地说,寻找这种模式非常有用(即,每个分支都具有基本相同的表达式)。在纸上写出真值表或以其他方式划分您的状态空间,可以帮助在更复杂的代码中阐明这些模式。

    您应该始终致力于了解一般情况是什么 - 无论是因为您首先实施了该情况,还是因为您能够将其从几个特定情况中提取出来。无论如何,通常实现一般情况就足够了,并且是最容易理解的逻辑版本。

    如果一般情况由于某种原因不够好,那么易于理解意味着它仍然是一个很好的注释,因为它为您实际实现的特殊情况提供了一个比较点。

    【讨论】:

      【解决方案2】:

      我猜是因为tree::findBalanceFactor方法中的这两行代码导致根节点的balance_factor总是为0的原因:

      if( p.lchild)   p.lchild->balance_factor=findBalanceFactor( *p.lchild );    
      if( p.rchild)   p.rchild->balance_factor=findBalanceFactor( *p.rchild );
      

      我想node 结构/类看起来像这样:

      struct node {
          struct node *lchild;
          struct node *rchild;
          int balance_factor;
          int height;
      };
      

      findBalanceFactor( *p.lchild )findBalanceFactor( *p.rchild ) 中发生的情况是,我们将p.lchildp.rchild新副本 传递到findBalanceFactor(从指针取消引用中可以看出),并且因此原始p.lchildp.rchildbalance_factor 属性不会更新。

      解决方案是修改tree::findBalanceFactor 方法以接收指向节点的指针,就像这样(我冒昧地对代码进行了一些美化):

      int tree::findBalanceFactor(node *p) {
          int a;
          if (p->lchild) {
              findBalanceFactor(p->lchild);
          }
          if (p->rchild) {
              findBalanceFactor(p->rchild);
          }
      
          if (p->rchild && p->lchild) {
              a = p->balance_factor = p->lchild->height - p->rchild->height;
          } else if (p->rchild && !p->lchild) {
              a = p->balance_factor = 0 - p->rchild->height;
          } else if (!p->rchild && p->lchild) {
              a = p->balance_factor = p->lchild->height;
          } else {
              // this is the case for !p->rchild && !p->lchild
              a = p->balance_factor = 0;
          }
      
          cout << "md" << a << endl;
          return a;
      }
      

      对于p-&gt;lchildp-&gt;rchild,我们不需要再次设置它们的balance_factor,因为每个nodebalance_factor 已经设置为很长@ 的四种可能情况之一987654341@声明。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多