• 技术文章 >后端开发 >php教程

    PHP兑现平衡二叉树(AVL树)

    2016-06-13 13:17:36原创296
    PHP实现平衡二叉树(AVL树)
    deleteNode('30');(非平衡树可删除,平衡树的没写删除操作)
        print_r($tree->getTree()); 
    ?>


    bstOrder.php
    data = $data;
                $this->left = $left;
                $this->right = $right;
                $this->bf = $bf;
            }
    
            public function getBf(){
                return $this->bf;
            }
    
            public function setBf($bf){
                $this->bf = $bf;
            }
    
            public function getData(){
                return $this->data;
            }
    
            public function setData($data){
                $this->data = $data;
            }
    
            public function &getLeft(){
                return $this->left;
            }
    
            public function &getRight(){
                return $this->right;
            }
    
            public function setLeft($left){
                $this->left = $left;
            }
    
            public function setRight($right){
                $this->right = $right;
            }
        }
    
        class Bst{
            private $head;//头结点
            private $data;//初始输入的数据,为数组形式,如array('a','b');
            private $tag;//查找时设置的前一结点(已无效,没用)
            
            //$bst:是否创建AVL树 
            public function Bst($data, $bst = FALSE){
                $this->data = $data;
                $this->head = NULL;
                
                if(!$bst){
                    $this->createBst();
                }else{
                    $this->createBfBst();
                }
            }
    
            public function createBfBst(){
                foreach($this->data as $value){
                    $this->insertBfNode($this->head, $value);   
                }
            }
    
            private function insertBfNode(&$node, $value){
                if($node == NULL){
                    $node = new Node($value, 0);  
                    return TRUE; 
                }else{
                    if($node->getData() > $value){
                        if(!$this->insertBfNode($node->getLeft(), $value)){
                            return FALSE;
                        }
    
                        switch($node->getBf()){
                            case 0:
                                $node->setBf(1);
                                return TRUE;
                            case 1:
                                $this->rightRotate($node);
                                return FALSE;
                            case -1:
                                $node->setBf(0);
                                return FALSE;
                        }
                    }elseif($node->getData() < $value){
                        if(!$this->insertBfNode($node->getRight(), $value)){
                            return FALSE;
                        }
    
                        switch($node->getBf()){
                            case 0:
                                $node->setBf(-1);
                                return TRUE;
                            case 1:
                                $node->setBf(0);
                                return FALSE;
                            case -1:
                                $this->leftRotate($node);
                                return FALSE;
                        }
                    }else{
                        return FAlse;
                    }
                }
            }
            
            private function excuteLeft(&$node){
                $temp = $node;
                $node = $node->getRight();
                $temp->setRight($node->getLeft());
                $node->setLeft($temp);
            }
    
            private function excuteRight(&$node){
                $temp = $node;
                $node = $node->getLeft();
                $temp->setLeft($node->getRight());
                $node->setRight($temp);
            }
    
            private function leftRotate(&$node){
                $right = &$node->getRight();
                switch($right->getBf()){
                    case 1:
                        $left = &$right->getLeft();
                        switch($left->getBf()){
                            case -1:
                                $right->setBf(0);
                                $node->setBf(1);
                                break;
                            case 0:
                                $right->setBf(0);
                                $node->setBf(0);
                                break;
                            case 1:
                                $right->setBf(-1);
                                $node->setBf(0);
                                break;
                        }
    
                        $left->setBf(0);
                        $this->excuteRight($right);
                        $this->excuteLeft($node);
                        break;
                        
                    case -1:
                        $node->setBf(0);
                        $right->setBf(0);
                        $this->excuteLeft($node);
                        break;
                }
            } 
    
            private function rightRotate(&$node){
                $left = &$node->getLeft();
                switch($left->getBf()){
                    case -1:
                        $right = &$left->getRight();
                        switch($right->getBf()){
                            case -1:
                                $left->setBf(1);
                                $node->setBf(0);
                                break;
                            case 0:
                                $left->setBf(0);
                                $node->setBf(0);
                                break;  
                            case 1:
                                $left->setBf(0);
                                $node->setBf(-1);
                                break;
                        }
                       
                        $right->setBf(0); 
                        $this->excuteLeft($left);
                        $this->excuteRight($node);
                        break;
                    case 1:
                        $node->setBf(0);
                        $left->setBf(0);
                        $this->excuteRight($node);
                        break;
                }
            }
    
            public function createBst(){
                foreach($this->data as $value){
                    $this->insertNode($value);
                }
            }
    
            //$pre:如果找不到该结点,是否返回前值
            public function &searchBst(& $node, $key, $pre = FALSE){
                if($node == NULL){
                    if($pre){
                        return $this->tag;
                    }else{
                        return FALSE;
                    }
                }
                
                if($key > $node->getData()){
                    $this->tag = $node;
                    return $this->searchBst($node->getRight(), $key, $pre);   
                }elseif($key < $node->getData()){
                    $this->tag = $node;
                    return $this->searchBst($node->getLeft(), $key, $pre);
                }else{
                    return $node;
                }
            }
    
            public function insertNode($key){
                if(!$this->head){
                    $this->head = new Node($key);
                }else{
                    $pre = $this->searchBst($this->head, $key, TRUE);
                    $node = new Node($key);
                   
                    if($pre->getData() > $key){
                        $pre->setLeft($node);   
                    }else{
                        $pre->setRight($node);
                    }
                }
            }
    
            public function deleteNode($key){
                $node = &$this->searchBst($this->head, $key);
                
                if(!$node){
                    return FALSE;   
                }
    
                if($node->getLeft() == NULL){
                    $node = $node->getRight(); 
                }elseif($node->getRight() == NULL){
                    $node = $node->getLeft(); 
                }else{
                    $leftBig = &$this->searchLeftBig($node);
                    $node->setData($leftBig->getData());
                    
                    if($leftBig->getLeft()){
                        $leftBig = $leftBig->getLeft();
                    }
                }
            }
    
            private function &searchLeftBig(& $key){
                $result = &$key->getLeft();
    
                while($result){
                    if($result->getRight() == NULL){
                        return $result;
                    }
    
                    $result = &$result->getRight();
                }
            }
    
            public function getTree(){
                return $this->head;
            }
        }
    ?>
    声明:本文原创发布php中文网,转载请注明出处,感谢您的尊重!如有疑问,请联系admin@php.cn处理
    专题推荐:Node gt this function return
    上一篇: 求一段正则提取代码解决思路 下一篇: php性能(内存)有关问题
    大前端线上培训班

    相关文章推荐

    • 怎样使用PHP中的spl_autoload_register() 和 __autoload() 函数?• 你必须了解PHP中什么是抽象类和抽象方法• PHP中怎样去判断对象是否属于一个类?• 五分钟带你看PHP中的接口interface声明与应用(实例详解)• PHP中怎样完成Cookie的创建、读取和删除?

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网