【问题标题】:How to balance binary tree in PHP without rotating parent?如何在没有旋转父级的情况下平衡 PHP 中的二叉树?
【发布时间】:2011-04-14 04:45:55
【问题描述】:

我会尽量让自己清楚。基于邻接表模型:http://articles.sitepoint.com/article/hierarchical-data-database

我需要一种方法来平衡这棵树

     0 
    / \ 
   1   2 
  /   / \ 
 3    4  5 
       \  \
        6  7

类似于:

        0 
      /   \ 
     1     2 
    / \   / \ 
   3   4 5   6
  /
 7

基于示例代码:

<?php 
function display_children($parent, $level) { 
   $result = mysql_query('SELECT title FROM tree '. 
                          'WHERE parent="'.$parent.'";'); 
   while ($row = mysql_fetch_array($result)) { 
       echo str_repeat('  ',$level).$row['title']."\n"; 
       display_children($row['title'], $level+1); 
   } 
} 
?>

我修改了代码,使它可以像这样输出一个扁平的 html 表格:

$super_parent = '0000' 左节点条目到平面列表中:

 ____________________________________________________
| No. | Date of Entry       | Account ID  | Placement|
------------------------------------------------------
| 1   | 2010-08-24 11:19:19 | 1111a       |    a     |
| 2   | 2010-08-24 11:19:19 | 22221a_a    |    a     |
| 3   | 2010-08-24 11:19:19 | 33_2aa      |    b     | 
| 4   | 2010-08-24 11:19:19 | 33_2Ra      |    a     | 
| 5   | 2010-08-24 11:19:19 | 22221a_b    |    b     |
| 6   | 2010-08-24 11:19:19 | 33_2ba      |    a     |
| 7   | 2010-08-24 11:19:19 | 33_2bb      |    b     |
------------------------------------------------------

但我需要一种方法来将所有这些重新组织成一棵平衡的树,而无需移动或旋转父级。虽然我可以考虑在数据库中创建一个重复的表并进行第二次查询以显示或创建另一个 Binaray 树,但我认为可以将这样的扁平树重新组织为:

        0 
      /   \ 
     1     2 
    / \   / \ 
   3   4 5   6
  /
 7

从左到右。 0 代表 parent 或 super_parent 0000。

我想这样做的原因是,我可以从原始树创建一个虚拟树,这将是我项目中另一个算法的基础。

提前致谢。

鲍勃

【问题讨论】:

    标签: php modified-preorder-tree-t tree-balancing


    【解决方案1】:

    这是我用来构建二叉树数据结构及其相应操作的完整代码:

    <?php
    class Node
    {
     public $data;
     public $leftChild;
     public $rightChild;
    
     public function __construct($data)
      {
       $this->data=$data;
       $this->leftChild=null;
       $this->rightChild=null;
      }
     public function disp_data()
      {
       echo $this->data;
      }
    
    
    }//end class Node
    class BinaryTree
    {
     public $root;
     //public $s;
     public function __construct()
      {
       $this->root=null;
       //$this->s=file_get_contents('store');
    
      }
    //function to display the tree
      public function display()
      {
       $this->display_tree($this->root);
    
      }
      public function display_tree($local_root)
      {
    
       if($local_root==null) 
         return;
        $this->display_tree($local_root->leftChild);
        echo $local_root->data."<br/>";
        $this->display_tree($local_root->rightChild);
    
      } 
    // function to insert a new node
      public function insert($key)
       {
        $newnode=new Node($key);
          if($this->root==null)
            {
             $this->root=$newnode;
             return;
            }
          else
            {
             $parent=$this->root;
             $current=$this->root;
               while(true)
                 {
                   $parent=$current;
                     //$this->find_order($key,$current->data);
                    if($key==($this->find_order($key,$current->data)))
                      {
                          $current=$current->leftChild;
                           if($current==null)
                             {
                              $parent->leftChild=$newnode;
                              return;
                             }//end if2
                      }//end if1 
                    else
                      {
                          $current=$current->rightChild;
                           if($current==null)
                             {
                              $parent->rightChild=$newnode;
                              return;  
                             } //end if1                       
                      } //end else
                 }//end while loop 
            }//end else
    
       } //end insert function
    
    //function to search a particular Node
     public function find($key)
      {
        $current=$this->root;
         while($current->data!=$key)
              {
                if($key==$this->find_order($key,$current->data))
                  {
                    $current=$current->leftChild;
                  }
                else
                  {
                    $current=$current->rightChild;
                  }
                if($current==null)
                  return(null);
    
              }
             return($current->data); 
      }// end the function to search
     public function delete1($key)
      {
        $current=$this->root;
        $parent=$this->root;
    
        $isLeftChild=true;
         while($current->data!=$key)
              {
               $parent=$current;
               if($key==($this->find_order($key,$current->data)))
                 {
                  $current=$current->leftChild;
                  $isLeftChild=true;
                 }   
               else
                 {
                  $current=$current->rightChild;
                  $isLeftChild=false;   
                 } 
                if($current==null)
                  return(null);
              }//end while loop 
    
          echo "<br/><br/>Node to delete:".$current->data;
         //to delete a leaf node 
         if($current->leftChild==null&&$current->rightChild==null)
           {
               if($current==$this->root)
                  $this->root=null;  
              else if($isLeftChild==true)
               {
                $parent->leftChild=null;
               }  
             else
               {
                $parent->rightChild=null;
               }
             return($current);       
           }//end if1
         //to delete a node having a leftChild 
       else if($current->rightChild==null)
           {
              if($current==$this->root)
               $this->root=$current->leftChild;
              else if($isLeftChild==true)
               {
                $parent->leftChild=$current->leftChild;
               }
              else
               {
                $parent->rightChild=$current->leftChild;
               }   
              return($current);
           }//end else if1
        //to delete a node having a rightChild
       else if($current->leftChild==null)
           {
             if($current==$this->root)
               $this->root=$current->rightChild;
             else if($isLeftChild==true)
               {
                $parent->leftChild=$current->rightChild;
               }  
             else
               {
                $parent->rightChild=$current->rightChild; 
               }  
               return($current);
           }  
       //to delete a node having both childs
        else
           {
            $successor=$this->get_successor($current);
            if($current==$this->root)
              {
                $this->root=$successor; 
    
              }
            else if($isLeftChild==true)
              {
               $parent->leftChild=$successor;
              }
            else
              {
               $parent->rightChild=$successor;
              }     
             $successor->leftChild=$current->leftChild;
            return($current);
           }   
    
    
      }//end the function to delete a node
    //Function to find the successor node
     public function get_successor($delNode)
      {
       $succParent=$delNode;
       $successor=$delNode;
       $temp=$delNode->rightChild;
        while($temp!=null)
             {
              $succParent=$successor;
              $successor=$temp;
              $temp=$temp->leftChild;
             }
       if($successor!=$delNode->rightChild)
         {
          $succParent->leftChild=$successor->rightChild;
          $successor->rightChild=$delNode->rightChild;
         }
      return($successor);
      }
    //function to find the order of two strings
     public function find_order($str1,$str2)
      {
         $str1=strtolower($str1);
         $str2=strtolower($str2);
         $i=0;
         $j=0;
    
         $p1=$str1[i];
         $p2=$str2[j]; 
      while(true)
       {  
           if(ord($p1)<ord($p2)||($p1==''&&$p2==''))
             {
    
               return($str1);
             }
          else
             {
               if(ord($p1)==ord($p2))
                 {
                  $p1=$str1[++$i];
                  $p2=$str2[++$j];
                  continue;
                 }
              return($str2); 
             }
       }//end while
    
      } //end function find string order
    
     public function is_empty()
      {
        if($this->root==null)
          return(true);
        else
          return(false);
      }
    }//end class BinaryTree
    ?>
    

    【讨论】:

    • sirin,你能给我看一份你的 PHP 脚本源吗?因为在这个页面这里没有正确渲染。
    【解决方案2】:

    我决定用这个发现来回答我自己的问题。一般来说,这可以称为从左到右递归自动化平衡二叉树的“分布方法”。该算法确保每个级别处理 64 对,其余的将被清除:)

    <?php
    function makeBTree($load, $colMult, $levCount){
        $exCol=$colMult;
        if($load<=$colMult){
            $exCol=$load;
        } if($load>0) {echo "Load: $load ";} else {echo "Load: 0 ";}
        echo "Level: $levCount ";
        echo "Columns: ";
    
        for($i=1;$i<=$exCol; $i++){
    
        }
    
        if($i<=64) {
            echo "<font color='violet'>".($exCol)." candidate for pairing if count matches with TEAM B</font> \n";
        } else {
            $limiter = ($i)-64; 
            echo "<font color='orange'>$i</font> - <font color='black'>64</font> = 
            <font color='blue'>$limiter auto-flushout</font> \n";   
        }
    
        $load -=$colMult; if($load>0) {echo "Load: $load ";} else {echo "Load: 0";}
        echo "<br />\n";
    
        if($load>=1){
            makeBTree($load,$colMult*2, $levCount+1);
        }
    }
    
    makeBTree(1000,1,1);
    ?>
    

    super parent的左前线节点应计为1。剩下8个条目,只需调用:

    makeBTree(8,1,1);
    

    谢谢

    奥利弗·鲍勃·拉古门

    【讨论】:

    • 虽然这是一种非 OOP 方法。二叉树已经制作完成。然后添加了这个sidelick二进制算法。
    • 好的,s-e-n-d 到我的 yah-oo m-a-i-l "pcc_webmaster" 请添加 at-y-a-hoo-dot com。我有一个新问题,与每天的配对数限制有关。请看一下如果您愿意提供帮助,我需要对此有清晰的了解。我的截止日期是 2011 年 2 月 27 日。
    • sirin,我想问一下你上面解释的这段代码的副本,以供个人学习。我的电子邮件地址是:“pcc_webmaster@yahoo.com”。提前致谢。奥利弗·鲍勃·拉古门
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-17
    • 1970-01-01
    相关资源
    最近更新 更多