AVL树学习

AVL树为什会出现?

我们之前有学习使用二叉查找树,但是二叉查找树在使用的时候也会出现一些问题,当恰好所有的数据都是按照大小顺序插入的话,就有可能将我们的二叉树编程链表,就导致树结构退化为链表结构。

什么是不平衡

其实不平衡就是一个节点下面的左子树和右子树的高度相差太多,没有雨露均沾,导致出现了不平衡的现象。

如何解决不平衡?

其实我们从局部看,不平衡的情况其实就归为四种。

  1. 左—左类型
    左-左类型其实对于这种情况,三个节点都连在左边,可以使用右旋的方式来调整,以5为终点将其向右旋转,然后9向下成为5的右节点。如果5这个节点有右节点的话,可以按照这样的方式移动
    右旋的动图
  2. 右-右类型
    这个也不用多说,都是类似的使用左旋的方式,我们首先先写出右旋和左旋的代码。
    class Node {
    public:
    	Node * left;
    	Node * right;
    	int height; //需要记录一下高度
    };
    
    class AVLTree {
    public:
    	AVLTree(){};
    	~AVLTree(){};
    	/***
    	R_Rotate穿进来的是那个有问题的节点
    	***/
    	Node* R_Rotate(Node * pa) { 
    		Node *leftNode = pa -> left; // 讲leftNode拿出来
    		pa -> right = leftNode -> right;
    		leftNode -> right = pa;
    		
    		//重新计算节点的高度
    		pa->height = getHeight(pa->left) > getHeight(pa->right) ? getHeight(pa->left) : getHeight(pa->right) ;
    		pa->height ++;
    		leftNode->height =  getHeight(leftNode->left) > getHeight(leftNode->right) ? getHeight(leftNode->left) : getHeight(leftNode->right) ;
    		leftNode->height ++;
    		return leftNode;
    	}
    	Node * L_Rotate(Node * pa) {
    		Node * R = pa->right;
    		pa -> right = R -> left;
    		R -> left = pa;
    		//重新计算节点的高度
    		pa->height = getHeight(pa->left) > getHeight(pa->right) ? getHeight(pa->left) : getHeight(pa->right) ;
    		pa->height ++;
    		R->height =  getHeight(R->left) > getHeight(R->right) ? getHeight(R->left) : getHeight(R->right) ;
    		R->height ++;
    		return R;
    		
    	}
    		
    	int getHeight(Node * node) {
    		if(node) return node->height;
    		return -1;
    	}
    	
    	Node* L_R_Rotate(Node * pa) {
    		pa->right = L_Rotate(pa -> right);
    		pa = R_Rotate(pa);
    		return pa;
    	}
    	
    	Node* R_L_Rotate(Node* pa) {
    		pa->left = R_Rotate(pa->left);
    		pa = L_Rotate(pa);
    		return pa;
    	}
    	//insert这里需要使用递归,因为我们需要从上到下进行调整
    	Node * Insert(Node * newNode,Node * T) {
    		
    		if(!T) {
    			T = newNode; 
    		} else if(newNode->val > T->val) {
    			
    			T -> right = Insert(newNode , T -> right); //往右子树上面插入
    			if(height(T->right) - height(T->left) == 2) {
    				// right right
    				if(T ->right->val < newNode -> val) {
    					T = L_Rotate(T);
    				} else //right left{
    					T = L_R_Rotate(T);	
    				}
    			}
    		} else if(newNode->val < T -> val) {
    			T -> left = Insert(newNode, T->left);
    			if(height(T->left) - height(T->right) == 2) {
    				// left left
    				if(T->left->val > newNode->val) {
    					T = R_Rotate(T);
    				} else // left right {
    					T = R_L_Rotate(T);
    				}
    			}
    		}
    		
    		T->height = getHeight(T->left) > getHeight(T->right) ? getHeight(T->left) : getHeight(T->right) ;
    		return T;
    	}
    	private:
    		Node * head;
    	
    };
    
发布了56 篇原创文章 · 获赞 5 · 访问量 1万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章