#pragma once#include <iostream>using namespace std; #defineNEG -1# Definezero 0#definepos 1template <class k,class v>struct avltreenode Node {k _key; of the tree v _value; avltreenode* _left; avltreenode* _right; avltreenode* _parent;int _bf; Avltreenode (Const k& key,const v& value): _key (Key), _value (value), _left (null), _right (null), _parent (null), &NBSP;_BF (0)//Balance factor value -1 0 1 (left high 1 equal Right height 1) {}};template<class k,class v>class avltree{typedef avltreenode< K, v> node;public:avltree (): _root (NULL) {}~avltree () {}bool insert (Const k& key, Const v& value)//Insert {if (_root == null) {_root = new node (Key,value) ;//empty tree insert return true directly;} node* cur = _root, *prev = null;//current and before &NBSP; node pointer while (cur) {if (cur->_key < key)//insert key larger than current node key jump to right {if (cur->_right) {//Right not empty continue prev = cur;cur = cur->_right;if (cur->_bf = = zero)//If the bf of the node is 0, the insertion (if successful) will change the value of the PREV->BF prev->_bf++;} else{//Insert Cur->bf ++cur->_right = new node (key,value) If right is empty reaches the insertion node position cur->_ Right->_parent = cur;cur->_bf++;break;}} else if (Cur->_key>key)//empathy left insert {if (cur->_left) {prev = cur;cur = cur->_left;if (Cur->_bf == zero) prev->_bf--;} Else{cur->_left = new node (key, value); cur->_left->_parent = cur;cur- >_bf--;break;}} Else//key equal, insert failed, change the balance factor back to {while (Prev&&cur->_bf == zero) {if (prev- >_left == cur) prev->_bf++;elseprev->_bf--;cur = prev;prev = prev->_ Parent;} Return fAlse;}} Insert end Adjust entire tree keep it balanced//height constant if (cur->_bf == zero) return true;else//height Change {// Find a node with a height of -2 or 2 rotation while (prev) {if (prev->_bf < -1)//Zogao 2{if (CUR->_BF &NBSP;<=&NBSP;-1)//Right-click {_rotater (prev);cout << "right-handed" <<endl;break;} else//Rotation {_rotatel (cur); _rotater (prev);cout << "left and Right" << endl;break;} else if (prev->_bf > 1)//Right high 2{if (cur->_bf >= 1)//L {_RotateL ( prev);cout << "left-handed" << endl;break;} else//right-left {_rotater (cur); _rotatel (prev);cout << "right-left" << endl;break;} Cur = prev;prev = prev->_parent;}} Return true;} Bool isbalance () {if (_root == null) return true;return _isbalance (_root);} Node* find (Const k& key) {node * cur = _root;while (cur) {if ( Cur->_key >&nbSp;key) cur = cur->_left;else if (Cur->_key < key) cur = cur- >_right;elsereturn cur;} Return null;} Bool remove (Const k& key) {if (_root == null) {return false;//empty tree delete failed}node * cur = _root, *prev = null;while (cur) {if (cur->_key < key)//delete location in cur right {if (cur->_right) {//Right non-empty, continue to find prev = cur;cur = cur->_ Right;} else//right empty, not found delete node return return false;} else if (Cur->_key>key)//delete location in left {if (cur->_left) {prev = cur;cur = Cur->_left;} Elsereturn false;} else{node* parent = cur->_parent;//Record Delete node parent if (cur->_left == null)// Delete node left empty, directly connect it to prev {if (prev == null) {//prev is empty, delete root node, change root node _root = cur->_ Right;delete cur;return true;} if (prev->_right == cur) {//prev Right to cur,cur right to the preV Right prev->_bf--;//balance factor decrease prev->_right = cur->_right;if (cur->_right) cur->_ Right->_parent = prev;} if (prev->_left == cur) {//prev left for curprev->_left = cur->_right;prev-> _bf++;if (Cur->_right) Cur->_right->_parent = prev;} delete cur;//releases the node cur = prev;//Cur prev points to the active node prev = cur->_parent;} else if (Cur->_right == null)//ditto cur right is empty {if (prev == null) {_root = cur->_left;delete cur;return true;} if (prev->_right == cur) {prev->_bf--;p rev->_right = cur->_left;if ( Cur->_left) Cur->_left->_parent = prev;} if (prev->_left == cur) {prev->_left = cur->_left;prev->_bf++;if ( Cur->_left) Cur->_left->_parent = prev;} Delete cur;cur = prev;prev = cur->_parent;} ElSe{//cur is not empty around, in order to avoid the current root of the complex operation, to remove the cur left child the right node  , or cur right child leftmost node, copy its contents to curnode* tmp = cur;prev = cur;cur = cur->_right;while (cur->_left)// Find the right tree the left {prev = cur;cur = cur->_left;} tmp->_key = cur->_key;tmp->_value = cur->_value;//copy value if (cur == prev->_left)//adjust PREV&NBSP;BF and connect cur right tree to prev prev->_bf++;p Rev->_left = cur->_right;} if (cur == prev->_right)//Ibid. {prev->_bf--;p rev->_right = cur->_right;} tmp = cur;//Record Delete location cur = prev;parent = cur;//cur prev point to active node prev = cur->_parent;delete tmp;//Delete tmp}while (Prev &&cur->_bf == zero)// Delete a node Parent tree height may change, confirm and modify bf (CUR&NBSP;BF to 0 description is -1 or 1 change height changes need to modify parent node &NBSP;BF) {if (cur == prev->_left) {prev->_bf++;} if (cur == prev->_right) {prev->_bf--;} Cur = prev;prev = prev->_parent;} Prev = parent;//prev Point The parent node of the actual delete node if (Prev->_bf < zero) cur = prev->_left;if (Prev->_bf > zero) cur = prev->_right;if (PREV->_BF == zero) {cur = prev;prev = prev->_parent;} Break;}} Find a node with a height of -2 or 2 rotation while (prev) {if (prev->_bf < -1)//Zogao 2{cur = prev->_left;//because deleting one side of a node may require the other side to rotate, the cur needs to be re-assigned if (cur && (cur->_bf <= -1 | | cur->_bf == zero)//Right-click {_rotater (prev);if (prev->_left&&prev->_right == null)//Judging the bfprev->_bf--;cout& of prev after rotationnbsp;<< "right-handed" &NBSP;<<&NBSP;ENDL;} else//Rotation {_rotatel (cur); _rotater (prev);cout << "left and Right" &NBSP;<<&NBSP;ENDL;} cur = prev->_parent;prev = cur->_parent;while (prev&&cur->_bf = = zero)//Modify the rotated prev bf{if (cur == prev->_left) prev->_bf++;elseprev->_bf--;cur = prev;prev = prev->_parent;}} else if (prev->_bf > 1)//Right high 2{cur = prev->_right;if (cur & & (cur->_bf >= 1 | | cur->_bf == zero)///L {_rotatel (prev);cout << "left-handed" << endl; if (Prev->_right&&prev->_left == null) prev->_bf++;} else//right-left {_rotater (cur); _rotatel (prev);cout << "right-left" &NBSP;<<&NBSP;ENDL;} cur = prev->_parent;prev = cur->_parent;while (prev&&cur->_bf = = zero) {if (CUR&NBSp;== prev->_left) prev->_bf++;elseprev->_bf--;cur = prev;prev = prev->_ Parent;}} cur = prev;if (prev) prev = prev->_parent;} Return true;} Private:node* _root;int _height (Node* root) {if (root == null) return 0;int left = 1, right =1;left += _height (root->_left); right += _ Height (root->_right); return left > right ? left : right;} Bool _isbalance (Node* root)//judge whether the balance of is &NBSP;BF match {if (Root == null) return true;/*if (root ->_left==null&&root->_right==null) return true;*/bool left = _isbalance (Root->_left); bool right = _isbalance (root->_right); int num1 = 1;num1+=_height (Root->_left); Int num2 = 1;num2+=_height (root->_right); (left == false | | right&nBsp;== false) {cout << "not balace!" << " key: " << root->_key << "bf: " << root->_bf << endl;return false;} if (NUM2-NUM1!=ROOT->_BF) {cout << "bf error!" << "key:" << root->_key << "bf: " << root->_bf << "A-B:" << num1-num2 << endl;return false;} if (ABS (NUM1-NUM2) <= 1) Return true;return false;} Post-rotation bf adjustment summary: left-hand bf decrease Right-turn bf increase; sub=2 ,parent change 3,sub change 2;sub=1,parent Change 2,sub change 1;void _rotater (node* parent)//right-handed {node* subl = parent->_left; node* sublr = subl->_right; node* ppnode=parent->_parent;subl->_right = parent;parent->_parent = subl; Parent->_left = sublr;if (SUBLR) sublr->_parent = parent;if (ppNode) {if ( ppnode->_left == parent) Ppnode->_left = subl;elseppnode->_right = subl;} else_root = subl;subl->_parent = ppnode;//Rotation//modification bfif (subl->_bf == -2) {parent->_bf = 1;subl->_bf=0;} else{subl->_bf++;p arent->_bf = 0;}} Void _rotatel (node* parent)//L-{node* subr= parent->_right; node* subrl = subr->_left; node* ppnode = parent->_parent;subr->_left = parent;parent->_parent = subR;parent->_right = subRL;if (SUBRL) subrl->_parent = parent;if ( Ppnode) {if (ppnode->_left == parent) ppnode->_left = subr;elseppnode->_right &NBSP;=&NBSP;SUBR;} else_root = subr;subr->_parent = ppnode;//above for left rotation//below modify bf value IF&NBSP; (subr->_bf == 2)//Right child's height for 2 description rotation before height difference in the right child's lower, after rotation parent right branch can not connect, height will drop 3 changed from 2 to -1{parent->_bf = -1;subr->_bf = 0;} else{ //Right Child height is 1, after rotation height will 2 buf to 0, while right child height will 1;parent->_bf = 0;subr->_bf-- ;}}};
C + + avltree (highly balanced search binary tree)