5、AVL树的实现

1、我们首先要计算节点的高度和平衡因子。

《5、AVL树的实现》

       //  计算每个节点的高度
       int   getHeight(Node<K, V> * node){
		if (node == NULL) return 0;
		return node->height;
	
	}


	// 获得节点node的平衡因子
	int getBalanceFactor(Node<K, V> * node){
		if (node == NULL)
			return 0;
		return getHeight(node->left) - getHeight(node->right);
	}

 

《5、AVL树的实现》

 

	// 判断以Node为根的二叉树是否是一棵平衡二叉树,递归算法
	bool isBalanced(Node<K,V> *node){
		if (node == NULL)
			return true;
		int balanceFactor = getBalanceFactor(node);
		if (abs(balanceFactor) > 1)
			return false;
		return isBalanced(node->left) && isBalanced(node->right);
	}


	// 判断该二叉树是否是一棵二分搜索树
	bool isBST(){
		vector<K> keys;
		inOrder(root, keys);
		for (int i = 1; i < keys.size(); i++)
		if (keys[i - 1]>keys[i])
			return false;
		return true;
	}
        //中序便利
	void inOrder(Node<K,V> * node, vector<K> keys){
		if (node == NULL)
			return;
		inOrder(node->left, keys);
		keys.push_back(node->key);
		inOrder(node->right, keys);
	}

 

《5、AVL树的实现》

 

 2、右旋转的操作

《5、AVL树的实现》

《5、AVL树的实现》 

 《5、AVL树的实现》

《5、AVL树的实现》 《5、AVL树的实现》

        // 对节点y进行向右旋转操作,返回旋转后新的根节点x
	//        y                              x
	//       / \                           /   \
	//      x   T4       向右旋转 (y)     z     y
	//     / \       - - - - - - - ->    / \   / \
	//    z   T3                       T1  T2 T3 T4
	//   / \
         // T1   T2
	Node<K,V> * rightRotate(Node<K,V> * y) {

		Node<K, V>   * x = y->left;
		Node<K, V> * T3 = x->right;
		x->right = y;
		y->right = T3;

		// 更新height
		y->height = max(getHeight(y->left), getHeight(y->right)) + 1;
		x->height = max(getHeight(x->left), getHeight(x->right)) + 1;
		return  x;
	}

3、左旋转的过程。

《5、AVL树的实现》

 《5、AVL树的实现》

 《5、AVL树的实现》

    // 对节点y进行向左旋转操作,返回旋转后新的根节点x
    //    y                             x
    //  /  \                          /   \
    // T1   x      向左旋转 (y)       y     z
    //     / \   - - - - - - - ->   / \   / \
    //   T2  z                     T1 T2 T3 T4
    //      / \
    //     T3 T4
	Node<K, V> *  leftRotate(Node<K, V>  *y) {
		Node<K, V>   * x = y->right;
		Node<K, V> * T2 = x->left;

		// 向左旋转过程
		x->left = y;
		y->right = T2;

		// 更新height
		y->height = max(getHeight(y->left), getHeight(y->right)) + 1;//顺序不能够改变
		x->height = max(getHeight(x->left), getHeight(x->right)) + 1;

		return x;
	}

 

 4、LL和RR  和 LR 和RL 过程。

《5、AVL树的实现》

 《5、AVL树的实现》

《5、AVL树的实现》

《5、AVL树的实现》

 《5、AVL树的实现》

 

                //1、添加结点就是一个不断的回溯的过程。
		node->height = 1 + max(getHeight(node->left), getHeight(node->right));  //计算结点的高度

		int BalanceFactor = getBalanceFactor(node);
		//LL
		if (BalanceFactor > 1 && getBalanceFactor(node->left) >= 0){
			return  rightRotate(node);

		}
		//RR
		if (BalanceFactor <-1 && getBalanceFactor(node->right) <= 0){
			return  leftRotate(node);

		}

		//LR
		if (BalanceFactor > 1 && getBalanceFactor(node->left) < 0){
			node->left = leftRotate(node->left);
			return  rightRotate(node);

		}
		//RL
		if (BalanceFactor <-1 && getBalanceFactor(node->right) >0){
			node->right = rightRotate(node->right);
			return  leftRotate(node);
		}
		return node;
	}

整个代码的实现

#ifndef AVLMAP2
#define AVLMAP2
#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
#include<cassert>
using namespace std;
template<class  K, class V>
struct  Node {
	K  key;
	V  value;
	Node *  left;
	Node *  right;
	int  height;
	Node(K  k, V  v) : key(k), value(v), left(NULL), right(NULL), height(1){}
};
template<class  K, class V>
class  AVLTree2{
private:
	Node<K, V>  * root;
	int   size;
	// 向以node为根的二分搜索树中插入元素e,递归算法
	Node<K, V>  * add(Node<K, V> * node, K k, V  v){
		if (node == NULL){
			size++;
			return new Node<K, V>(k, v);
		}
		if (k < node->key){  //表示的是 该值比较小,并且它的左孩子为NULL
			node->left = add(node->left, k, v);  //去节点的左边找。
		}
		else  if (k > node->key){  //表示的是该值比较大,并且它的右孩子为NULL
			node->right = add(node->right, k, v);//去节点的右边找。
		}
		else{
			node->value = v;
		}

		//1、添加结点就是一个不断的回溯的过程。
		node->height = 1 + max(getHeight(node->left), getHeight(node->right));  //计算结点的高度

		int BalanceFactor = getBalanceFactor(node);
		//LL
		if (BalanceFactor > 1 && getBalanceFactor(node->left) >= 0){
			return  rightRotate(node);

		}
		//RR
		if (BalanceFactor <-1 && getBalanceFactor(node->right) <= 0){
			return  leftRotate(node);

		}

		//LR
		if (BalanceFactor > 1 && getBalanceFactor(node->left) < 0){
			node->left = leftRotate(node->left);
			return  rightRotate(node);

		}
		//RL
		if (BalanceFactor <-1 && getBalanceFactor(node->right) >0){
			node->right = rightRotate(node->right);
			return  leftRotate(node);
		}
		return node;
	}
	int   getHeight(Node<K, V> * node){
		if (node == NULL) return 0;
		return node->height;
	
	}


	// 获得节点node的平衡因子
	int getBalanceFactor(Node<K, V> * node){
		if (node == NULL)
			return 0;
		return getHeight(node->left) - getHeight(node->right);
	}




	// 中序遍历以node为根的二分搜索树, 递归算法
	void inOrder(Node<K, V> * node){
		if (node == NULL)
			return;
		inOrder(node->left);
		cout << node->key << " ";
		inOrder(node->right);
	}



	// 返回以node为根节点的二分搜索树中,key所在的节点
	Node<K, V> * getNode(Node<K, V> * node, K key){
		if (node == NULL)
			return NULL;
		if (key == node->key)
			return node;
		else if (key < node->key)
			return getNode(node->left, key);
		else // if(key.compareTo(node.key) > 0)
			return getNode(node->right, key);
	}


	// 对节点y进行向右旋转操作,返回旋转后新的根节点x
	//        y                              x
	//       / \                           /   \
	//      x   T4       向右旋转 (y)     z     y
	//     / \       - - - - - - - ->    / \   / \
	//    z   T3                       T1  T2 T3 T4
	//   / \
     // T1   T2
	Node<K,V> * rightRotate(Node<K,V> * y) {

		Node<K, V>   * x = y->left;
		Node<K, V> * T3 = x->right;
		x->right = y;
		y->right = T3;

		// 更新height
		y->height = max(getHeight(y->left), getHeight(y->right)) + 1;
		x->height = max(getHeight(x->left), getHeight(x->right)) + 1;
		return  x;
	}


	// 对节点y进行向左旋转操作,返回旋转后新的根节点x
	//    y                             x
	//  /  \                          /   \
        // T1   x      向左旋转 (y)       y     z
	//     / \   - - - - - - - ->   / \   / \
        //   T2  z                     T1 T2 T3 T4
	//      / \
        //     T3 T4
	Node<K, V> *  leftRotate(Node<K, V>  *y) {
		Node<K, V>   * x = y->right;
		Node<K, V> * T2 = x->left;

		// 向左旋转过程
		x->left = y;
		y->right = T2;

		// 更新height
		y->height = max(getHeight(y->left), getHeight(y->right)) + 1;//顺序不能够改变
		x->height = max(getHeight(x->left), getHeight(x->right)) + 1;

		return x;
	}
public:

	AVLTree2(){
		root = NULL;
		size = 0;
	}

	void add(K key, V value){
		root = add(root, key, value);
	}


	V remove(K key){
		Node<K, V> * node = getNode(root, key);
		if (node != NULL){  //如果存在
			root = remove(root, key);
			return node->value;
		}
		return NULL;
	}

	void inOrder(){
		inOrder(root);
	}
	// 删除掉以node为根的二分搜索树中值为e的节点, 递归算法
	// 返回删除节点后新的二分搜索树的根
	Node<K, V> * remove(Node<K, V>  * node, K e){

		if (node == NULL)
			return NULL;

		Node<K, V> * res;

		if (e<node->key){
			node->left = remove(node->left, e);
			res = node;
			//return node;
		}
		else if (e>node->key){
			node->right = remove(node->right, e);
			res = node;
		}
		else{   // e.compareTo(node.e) == 0

			// 待删除节点左子树为空的情况
			if (node->left == NULL){
				Node<K, V> * rightNode = node->right;
				node->right = NULL;
				size--;
				res = rightNode;
			//	return rightNode;
			}

			// 待删除节点右子树为空的情况
			else if (node->right == NULL){
				Node<K, V>  * leftNode = node->left;
				node->left = NULL;
				size--;
				res= leftNode;
			}
			else{
				// 待删除节点左右子树均不为空的情况

				// 找到比待删除节点大的最小节点, 即待删除节点右子树的最小节点
				// 用这个节点顶替待删除节点的位置
				Node<K, V>  *  successor = minimum(node->right);
				successor->right = remove(node->right,node->key);
				successor->left = node->left;
				node->left = node->right = NULL;

				res = successor;
			    //	return successor;
			}
		}

		if (res == NULL)  return NULL;

		//1、添加结点就是一个不断的回溯的过程。
		res->height = 1 + max(getHeight(res->left), getHeight(res->right));  //计算结点的高度

		int BalanceFactor = getBalanceFactor(res);
		//LL
		if (BalanceFactor > 1 && getBalanceFactor(res->left) >= 0){
			return  rightRotate(res);

		}
		//RR
		if (BalanceFactor <-1 && getBalanceFactor(res->right) <= 0){
			return  leftRotate(res);

		}

		//LR
		if (BalanceFactor > 1 && getBalanceFactor(res->left) < 0){
			res->left = leftRotate(res->left);
			return  rightRotate(res);

		}
		//RL
		if (BalanceFactor <-1 && getBalanceFactor(res->right) >0){
			res->right = rightRotate(res->right);
			return  leftRotate(res);
		}


		return res;
	}

	bool contains(K key){
		Node<K, V> * node = getNode(root, key);
		if (node == NULL) { return false; }
		return true;
	}
	V get(K key){
		Node<K, V> * node = getNode(root, key);
		return node == NULL ? NULL : node->value;
	}

	void set(K key, V newValue){
		Node<K, V> * node = getNode(root, key);
		if (node == NULL)  cout << "不存在该值" << endl;
		else{
			node->value = newValue;
		}
	}
	int getSize(){ return size; }
	bool isEmpty(){ return  size == 0; }


	// 返回以node为根的二分搜索树的最小值所在的节点
	Node<K, V> * minimum(Node<K, V>  * node){
		if (node->left == NULL)
			return node;
		return minimum(node->left);
	}


	// 删除掉以node为根的二分搜索树中的最小节点
	// 返回删除节点后新的二分搜索树的根
	/*
	Node<K, V> * removeMin(Node<K, V> * node){
		if (node->left == NULL){
			Node<K, V> * rightNode = node->right;
			node->right = NULL;
			size--;
			return rightNode;
		}
		node->left = removeMin(node->left);
		return node;
	}
	*/

	// 判断该二叉树是否是一棵平衡二叉树
	bool isBalanced(){
		return isBalanced(root);
	}

	// 判断以Node为根的二叉树是否是一棵平衡二叉树,递归算法
	bool isBalanced(Node<K,V> *node){
		if (node == NULL)
			return true;
		int balanceFactor = getBalanceFactor(node);
		if (abs(balanceFactor) > 1)
			return false;
		return isBalanced(node->left) && isBalanced(node->right);
	}


	// 判断该二叉树是否是一棵二分搜索树
	bool isBST(){
		vector<K> keys;
		inOrder(root, keys);
		for (int i = 1; i < keys.size(); i++)
		if (keys[i - 1]>keys[i])
			return false;
		return true;
	    }

	void inOrder(Node<K,V> * node, vector<K> keys){
		if (node == NULL)
			return;
		inOrder(node->left, keys);
		keys.push_back(node->key);
		inOrder(node->right, keys);
	}




};
#endif;

 

    原文作者:AVL树
    原文地址: https://blog.csdn.net/qq_30272539/article/details/83790204
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞