• [alv]平衡二叉树


    class AVLNode{
    
        public $data;             // 节点数据
        public $left = null;      // 左子结点
        public $right = null;     // 右子节点
        public $bf = 0;           // 平衡因子BF
        public $parent = null;    // 存储父节点
    
        public function __construct($data)
        {
            $this->data = $data;
        }
    }
    class AVLTree {
    	private $root;
    
    	const LH = 1;   // 左子树高(高度差)
        const EH = 0;   // 等高
        const RH = -1;  // 右子树高(高度差)
    
        public function insert($data){
        	$this->insert_node($this->root,$data);
        }
        public function insert_node(&$tree,$data){
    		if(!$tree){
    			$tree = new AVLNode($data);
    			$tree->bf = self::EH;
    			return true;
    		}    	
    		//小于节点的数值
    		if($data < $tree->data){
    			if(!$this->insert_node($tree->left,$data)){
    				return false;
    			}else{
    				if(empty($tree->left->parent)){
    					$tree->left->parent=$tree;
    				}
    			}
    			switch ($tree->bf) {
    				case self::LH:
    					$this->left_balance($tree);
    					return false;
    				case self::EH:
    					$tree->bf= self::LH;
    					return true;
    				case self::RH:
    					$tree->bf=self::EH;
    					return false;
    			}
    		}else{
    			if(!$this->insert_node($tree->right,$data)){
    				return false;
    			}else{
    				if(empty($tree->right->parent)){
    					$tree->right->parent=$tree;
    				}
    			}
    			switch ($tree->bf) {
    				case self::LH:
    					$tree->bf = self::EH;
    					return false;
    				case self::EH:
    					$tree->bf = self::RH;
    					return true;
    				case self::RH:
    					$this->right_balance($tree);
    					return false;
    			}
    		}
        }
    
        public function left_balance(&$tree){
        	$subTree = $tree->left;
        	switch ($subTree->bf) {
        		case self::LH:
        			$subTree->bf = $tree->bf = self::EH;
        			$this->right_rotate($tree);
        			break;
        		case self::RH:
        			$subTree_r = $subTree->right;
        			switch ($subTree_r->bf) {
        				case self::LH:
        					$tree->bf  = self::LH;
        					$subTree->bf = self::EH;
        					break;
        				case self::RH:
        				   $tree->bf = self::EH;
        				   $subTree->bf = self::LH;
        				   break;
        			}
        		$subTree_r->bf = self::EH;
        		$this->left_rotate($subTree);
        		$this->right_rotate($tree);
        		break;
        	}
        }
    
        public function right_balance(&$tree){
        	$subTree = $tree->right;
        	switch ($subTree->bf) {
        		case self::RH:
        			$tree->bf = $subTree->bf = self::EH;
        			$this->left_rotate($tree);
        			break;
        		case self::LH:
        			$subTree_r = $subTree->left;
        			switch ($subTree_r->bf) {
        				case self::RH:
        					$tree->bf = self::LH;
        					$subTree->bf = self::EH;
        					break;
        				case self::LH:
        					$tree->bf = self::EH;
        					$subTree->bf = self::RH;
        					break;
        				case self::EH:
        					$tree->bf = $subTree->bf = self::EH;
        					break;
        			}
        			$subTree_r->bf = self::EH;
        			$this->right_rotate($subTree);
        			$this->left_rotate($tree);
        			break;
        	}
        }
    
        //左旋转
        public function left_rotate(&$tree){
        	$subTree = $tree->right;
        	if($tree->parent){
        		$subTree->parent = $tree->parent;
        		$left = true;
        		if($subTree->parent->right == $tree){
        			$left=false; 
        		}
        	}else{
        		$subTree->parent = null;
        	}
    
        	$tree->right = $subTree->left;
        	$tree->parent = $subTree;
        	$subTree->left = $tree;
    
        	$tree = $subTree;
        	if(!$tree->parent){
        		$this->root = $tree;
        	}else{
        		if($left){
        			$tree->parent->left = $tree;
        		}else{
        			$tree->parent->right= $tree;
        		}
        	}
        }
    
        //右旋转
        public function right_rotate($tree){
        	$subTree = $tree->left;
        	if($tree->parent){
        		$subTree->parent = $tree->parent;
        		$left = false;
        		if($tree->parent->left == $tree){
        			$left = true;
        		}	
        	}else{
        		$subTree->parent = null;
        	}
    
        	$tree->left = $tree->right;
        	$tree->parent = $subTree;
        	$subTree->parent = $subTree;
    
        	$tree = $subTree;
    
        	if(!$tree->parent){
        		$this->root = $tree;
        	}else{
        		if($left){
        			$tree->parent->left = $tree;
        		}else{
        			$tree->parent->right = $tree;
        		}
        	}
        }
    }
    
    $avlTree = new AVLTree();
    $avlTree->insert(3);
    $avlTree->insert(2);
    $avlTree->insert(1);
    print_r($avlTree);
    

      

  • 相关阅读:
    虚方法的调用是怎么实现的(单继承VS多继承)
    C++ Data Member内存布局
    删除单链表,你会吗?
    最近面试遇到的Windows相关的题目
    C# 文章导航
    移动端开发文章导航
    Vue源码阅读(一) 准备工作
    vue-router源码阅读(一) 内部探究
    Vuex源码阅读(二) store内的getters实现逻辑
    Vuex源码阅读(一) new Vuex.Store()内部探究
  • 原文地址:https://www.cnblogs.com/zh718594493/p/12089480.html
Copyright © 2020-2023  润新知