以前学习AVL树,便照着书上(《Data structure and program design in C++》)的插入代码敲了一遍加深印象(去掉书上的继承)。ios
1.AVL树是一种平衡二叉树,经过保持每个节点的两棵子树的高度差不能超过1来保持树的平衡性。函数
2.平衡性的保持:当插入新节点时,就可能破坏树的平衡性,针对某一个平衡性被破坏的节点的平衡操做(假设子树已经平衡,递归操做)有4种状况:学习
case1:插入后左子树更高且左子树的左子树比右子树高,此时进行右旋操做测试
case2:插入后左子树更高且左子树的右子树比左子树高,此时进行双旋转操做spa
case3:插入后右子树更高且右子树的右子树比左子树高,此时进行左旋操做code
case4:插入后右子树更高且右子树的左子树比右子树高,此时进行双旋转操做blog
其实只须要分红case1和case2两种状况,case3 和case4只是相反的位置而已继承
3.代码实现:递归
1)插入操做insert()函数调用avl_insert()函数ci
2)taller变量的设置很是巧妙,用以判断子树是否已经增高
3)一旦子树增高则判断是否须要进行平衡性操做
4)如下代码只实现插入操做,中序遍历用以测试
#include <iostream> using namespace std; enum Balance_factor { left_higher, equal_height, right_higher }; template<class Entry> struct Avl_Node { Entry data; Balance_factor balance; Avl_Node* left; Avl_Node* right; Avl_Node(Entry& x) { data = x; left = NULL; right = NULL; balance = equal_height; } Avl_Node() { left = right = NULL; balance = equal_height; } Balance_factor get_balance() { return balance; } void set_balance(Balance_factor x) { balance = x; } }; template<class Entry> class AVL_Tree { public: AVL_Tree(); bool insert(Entry& x); bool Remove(Entry& x); void Inorder(); //中序遍历 void recursive_inorder(Avl_Node<Entry>*); protected: Avl_Node<Entry>* root; bool avl_insert(Avl_Node<Entry>* &subroot, Entry& newdata, bool &taller); void rotate_left(Avl_Node<Entry>* &subroot); //左旋 void rotate_right(Avl_Node<Entry>* &subroot); //右旋 void left_balance(Avl_Node<Entry>* &subroot); //操做左子树保持平衡 void right_balance(Avl_Node<Entry>* &subroot); //操做右子树保持平衡 }; //构造函数 template<class Entry> AVL_Tree<Entry>::AVL_Tree() { root = NULL; } //插入数据 template<class Entry> bool AVL_Tree<Entry>::insert(Entry& x) { bool taller; return avl_insert(root, x, taller); } //删除数据 template<class Entry> bool AVL_Tree<Entry>::Remove(Entry& x) { } template<class Entry> bool AVL_Tree<Entry>::avl_insert(Avl_Node<Entry>* &subroot, Entry& newdata, bool &taller) { bool result = true; if (subroot == NULL) { subroot = new Avl_Node<Entry>(newdata); } else if (newdata < subroot->data) { //插入到左子树 result = avl_insert(subroot->left, newdata, taller); //插入到子树完成后判断子树高度是否增长,若增长,则可能致使不平衡,进行平衡处理 if (taller) { switch (subroot->get_balance()) { case left_higher : //若原来左边更高,在左子树插入后必然使得左边继续增高,致使不平衡,必须进行平衡操做 left_balance(subroot); taller = false; break; case equal_height : //若原来两边同样高,那么插入一个能够继续保持差值为1的平衡性,高度一定增长 subroot->set_balance(left_higher); break; case right_higher: //若原来右子树更高,那么增长左子树高度能够使树两边高度一致 taller = false; subroot->set_balance(equal_height); break; } } } else { result = avl_insert(subroot->right, newdata, taller); if (taller) { switch (subroot->get_balance()) { case left_higher: taller = false; subroot->set_balance(equal_height); break; case equal_height : subroot->set_balance(right_higher); break; case right_higher : right_balance(subroot); taller = false; break; } } } return result; } //左旋操做 template<class Entry> void AVL_Tree<Entry>::rotate_left(Avl_Node<Entry>* &subroot) { if (subroot == NULL || subroot->right == NULL) { cout << "subroot or subroot->right is NULL" << endl; } else { Avl_Node<Entry>* right_tree = subroot->right; subroot->right = right_tree->left; right_tree->left = subroot; subroot = right_tree; } } //右旋操做 template<class Entry> void AVL_Tree<Entry>::rotate_right(Avl_Node<Entry>* &subroot) { if (subroot == NULL || subroot->left == NULL) { cout << "subroot of subroot->left is NULL" << endl; } else { Avl_Node<Entry>* left_tree = subroot->left; subroot->left = left_tree->right; left_tree->right = subroot; subroot = left_tree; } } //重点,保持树的平衡操做,left_balance()函数为左子树太高时进行,right_balance()相反 template<class Entry> void AVL_Tree<Entry>::left_balance(Avl_Node<Entry>* &subroot) { Avl_Node<Entry>* left_tree = subroot->left; switch (left_tree->get_balance()) { case left_higher : //case1 subroot->set_balance(equal_height); left_tree->set_balance(equal_height); rotate_right(subroot); break; case equal_height : //error cout << "WARNING: program error detected in left_balance" << endl; case right_higher : //case 2 : double rotation Avl_Node<Entry>* subtree = left_tree->right; switch (subtree->get_balance()) { case left_higher : subroot->set_balance(right_higher); left_tree->set_balance(equal_height); break; case equal_height : subroot->set_balance(equal_height); left_tree->set_balance(equal_height); break; case right_higher : subroot->set_balance(equal_height); left_tree->set_balance(left_higher); } subtree->set_balance(equal_height); rotate_left(left_tree); rotate_right(subroot); break; } } template<class Entry> // The same as left_balance void AVL_Tree<Entry>::right_balance(Avl_Node<Entry>* &subroot) { Avl_Node<Entry>* right_tree = subroot->right; switch (right_tree->get_balance()) { case right_higher : //case3 subroot->set_balance(equal_height); right_tree->set_balance(equal_height); rotate_left(subroot); case equal_height : //error cout << "WARNING: program error detected in left_balance" << endl; case left_higher : //case4 Avl_Node<Entry>* subtree = right_tree->left; switch (subtree->get_balance()) { case left_higher : subroot->set_balance(equal_height); right_tree->set_balance(right_higher); break; case equal_height : subroot->set_balance(equal_height); right_tree->set_balance(equal_height); break; case right_higher : subroot->set_balance(left_higher); right_tree->set_balance(equal_height); break; } subtree->set_balance(equal_height); rotate_right(right_tree); rotate_left(subroot); break; } } //Test:inorder traversal template<class Entry> void AVL_Tree<Entry>::Inorder() { recursive_inorder(root); } template<class Entry> void AVL_Tree<Entry>::recursive_inorder(Avl_Node<Entry>* subroot) { if (subroot != NULL) { recursive_inorder(subroot->left); cout << subroot->data << endl; recursive_inorder(subroot->right); } } int main() { AVL_Tree<int> avl; for (int i = 0; i < 10; i++) { int u; cin >> u; avl.insert(u); } avl.Inorder(); return 0; }
若代码有误望能指点,thanks
Next step:SPLY Tree