码迷,mamicode.com
首页 > 其他好文 > 详细

平衡二叉树

时间:2019-12-24 10:19:12      阅读:74      评论:0      收藏:0      [点我收藏+]

标签:self   amp   节点   this   vlt   php   节点数据   sel   数据   

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);

  

平衡二叉树

标签:self   amp   节点   this   vlt   php   节点数据   sel   数据   

原文地址:https://www.cnblogs.com/zh718594493/p/12089480.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!