`

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

阅读更多
<?php
    require 'bstOrder.php';

    $test = range(1, 10);
    //$test = array(3,9,1,4,8,5,7,6,2,10);
    $tree = new Bst($test, true);
    //$tree->deleteNode('30');(非平衡树可删除,平衡树的没写删除操作)
    print_r($tree->getTree()); 
?>


bstOrder.php
<?php
    /**
     * PHP实现二叉排序树
     * @author zhaojiangwei
     * @since 2011/11/16 16:29
     *
     */

    class Node{
        private $data;
        private $left;
        private $right;
        private $bf;//平衡度

        public function Node($data = NULL, $bf = 0, $left = NULL, $right = NULL){
            $this->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实现二叉树图

    为了更高效地处理大数据,还可以考虑使用平衡二叉树,如AVL树或红黑树。 在PHP中实现二叉树,还需要考虑错误处理、内存管理以及如何将二叉树序列化和反序列化,以便在持久存储中保存和恢复。此外,还可以扩展这个...

    PHP实现绘制二叉树图形显示功能详解【包括二叉搜索树、平衡树及红黑树】

    二叉树的种类繁多,包括二叉搜索树(BST)、平衡二叉树(AVL树)、红黑树等,每种树都有其特定的用途和特性。 接下来,我们以PHP语言为例,探讨如何利用PHP实现二叉树的图形显示功能。这部分主要包括以下几个核心...

    PHP完全二叉树定义与实现方法示例

    - 平衡二叉树(如AVL树、红黑树)和二叉搜索树是二叉树的特殊类型,它们在保持数据有序的同时,优化了查找和插入操作的性能。 总之,完全二叉树是一种高效的数据结构,适合于存储和检索大量有序数据。PHP中的实现...

    PHP Class&amp;Object -- 解析PHP实现二叉树

    二叉树及其变体,如二叉搜索树(BST)、平衡二叉树(AVL)、红黑树等,在处理需要快速查找、插入和删除数据时非常有用。它们在数据库索引、搜索算法、解析表达式等领域有着广泛的应用。二叉树可以通过简单的方式维持...

    PHP构造二叉树算法示例

    在实际应用中,二叉树可以用来实现很多高级数据结构,如二叉搜索树、平衡树(AVL树、红黑树等),它们有各自的特性,适用于不同的场景。了解和掌握二叉树的构造、遍历以及相关算法对于解决复杂问题有着重要的意义。

    PHP基于非递归算法实现先序、中序及后序遍历二叉树操作示例

    而在某些数据结构如AVL树或红黑树中,后序遍历对于保持树的平衡至关重要。 了解和掌握二叉树遍历算法,不仅可以提升编程能力,也能加深对数据结构的理解,为解决复杂问题提供基础。通过练习和实践,可以更好地运用...

    PHP各种数据结构实现

    5. 树(Tree):树是一种非线性的数据结构,包括二叉树、平衡树(如AVL树、红黑树)等。在PHP中,通常通过嵌套的对象或数组来表示树形结构。 6. 图(Graph):图由顶点和边构成,可以用来表示复杂的关联关系。PHP...

    Algorithm-The-Algorithms-PHP.zip

    例如,二叉树的遍历(前序、中序、后序)、平衡二叉树(AVL树、红黑树)的构造与操作,以及哈希表的查找和插入等,都是提升程序效率的关键。 综上所述,"Algorithm-The-Algorithms-PHP.zip"这个资源包是学习和提高...

    PHP Class&amp;Object -- PHP 自排序二叉树的深入解析

    为了避免这种情况,可以使用自平衡二叉树,如AVL树或红黑树,它们在每次插入或删除后都能自动调整以保持平衡。 总的来说,自排序二叉树在PHP中是一种强大且高效的工具,适用于需要动态维护有序集合的场景,例如...

    PHP也可以写数据结构和算法.zip

    3. 树:二叉树、平衡树(如AVL树和红黑树)在PHP中可以使用类和对象来构造。每个节点代表一个元素,包含数据以及指向左子树和右子树的引用。 4. 图:图数据结构在PHP中通常通过邻接矩阵或邻接表来表示,用于处理...

    PhpSearchTree.zip

    "PhpSearchTree.zip"中的代码可能包括了更多关于二叉搜索树的高级操作,比如前序遍历、中序遍历和后序遍历,以及对平衡二叉树(如AVL树或红黑树)的实现。这些高级话题有助于进一步了解二叉搜索树的性能优化和应用...

    数据结构之利用PHP实现二分搜索树

    数据结构中的二分搜索树(Binary Search Tree,...为了保持高效性,可以使用自平衡二分搜索树,如AVL树或红黑树,它们通过自动调整树的结构来确保平衡。但在PHP中,由于没有内置支持,实现自平衡二分搜索树会更复杂。

    学习数据结构和算法必知必会的50个代码实现源码,实现的语言php、c、java、javascirpt、pythongo note

    - **树**:包括二叉树、平衡树(如AVL树、红黑树)、堆(最大堆和最小堆)等,广泛应用于搜索和排序。 - **图**:表示节点之间的关系,用于模拟网络和复杂的关系结构。 - **哈希表**:通过散列函数快速查找,实现...

    php 算法大全,用 PHP 的方式实现的各类算法合集

    5. 树:包含父节点和子节点的数据结构,如二叉树、平衡树(AVL、红黑树)等。 6. 图:由节点和边构成,可以表示复杂关系,如图遍历(深度优先搜索、广度优先搜索)。 四、动态规划 动态规划是一种解决最优化问题的...

    数据结构、PHP等资料.rar

    5. 树:数据元素间存在层级关系,如二叉树、平衡树(AVL树、红黑树)等,常用于搜索、排序问题。 6. 图:表示对象之间的复杂关系,如邻接矩阵、邻接表,应用于路由、社交网络分析等。 7. 哈希表:通过散列函数实现...

    数据结构(PHP描述).zip

    树是一种非线性数据结构,包括二叉树、平衡树(如AVL树和红黑树)、堆(如最小堆和最大堆)。在PHP中,虽然没有内置的树结构,但可以通过自定义类来构建树形数据。例如,二叉搜索树用于快速查找,堆常用于优先级队列...

    数据结构与算法分析:php语言描述

    二叉树包括多种类型,如二叉搜索树、AVL树等。 **B树(B-Tree)** - B树是一种自平衡的树数据结构,常用于数据库和文件系统中。 **平衡树** - 平衡树是一种特殊的二叉树,它保证了树的高度尽可能小,从而提高了查询...

    PHP算法与数据结构学习.zip

    更高级的数据结构,如树(二叉树、平衡树如AVL和红黑树)、图、哈希表等,也有其独特的应用场景。理解这些数据结构可以帮助我们设计出更高效、更优雅的解决方案。 在“zyqmv”这个文件名中,可能是一个目录或者一个...

    php_struct_demo:php数据结构算法

    二叉树、平衡树(如AVL树、红黑树)在PHP中常用于搜索和排序。树的实现通常需要自定义类,包括节点数据、左右子节点引用等属性。 6. **图**:图由顶点和边构成,用于表示实体之间的关系。PHP可以通过数组或对象来...

Global site tag (gtag.js) - Google Analytics