C++数据结构之AVL树

来源:互联网 发布:软件杂志编委 编辑:程序博客网 时间:2024/05/27 03:28

AVL树是最先发明的自平衡二叉查找树。AVL树得名于它的发明者 G.M. Adelson-Velsky 和 E.M. Landis,他们在 1962 年的论文 "An algorithm for the organization of information" 中发表了它。 在AVL树中,查找、删除和插入在最坏情况下的时间复杂度都是O(logn),增加、删除等操作可能需要对树进行一次或者多次旋转来使树重新平衡。我们在这里主要讨论AVL树的旋转问题。 首先是右旋:如图

右旋第二种情况:


左旋:

1:

2:

双旋:

左右双旋1:

左右双旋2:

右左双旋1:

右左双旋2:

AVL树的难点在于平衡树时进行的旋转操作,大家可以多多画图帮助理解,只要理解透彻,代码就很好完成。AVL树是最早的自平衡二叉树,相比于后来出现的平衡二叉树(红黑树,treap,splay树)而言,它现在应用较少,但研究AVL树对于了解后面出现的常用平衡二叉树具有重要意义。

源码如下:

#include<iostream>#include<assert.h>using namespace std;template<class K,class V>struct AVLTreeNode{K _key;V _value;AVLTreeNode<K, V>* _left;AVLTreeNode<K, V>* _right;AVLTreeNode<K, V>* _parent;int _bf;AVLTreeNode(const K& key, const V& value): _key(key), _value(value), _left(NULL), _right(NULL), _parent(NULL), _bf(0){}};template<class K,class V>class AVLTree{typedef AVLTreeNode<K, V> Node;public:AVLTree():_root(NULL){}bool Insert(const K& key,const V& value){if (_root == NULL){_root = new Node(key,value);return true;}Node* cur = _root;Node* parent= NULL;while (cur){if (cur->_key < key){parent = cur;cur = cur->_right;}else if (cur->_key > key){parent = cur;cur = cur->_left;}else{return false;}}cur = new Node(key, value);if (parent->_key < key){parent->_right = cur;cur->_parent = parent;}else{parent->_left = cur;cur->_parent = parent;}while (parent){if (cur->_bf == 0 && cur->_left != NULL && cur->_right != NULL){break;}if (parent->_left == cur){parent->_bf--;}else{parent->_bf++;}if (parent->_bf == 2 && parent->_bf == -2){break;}cur = parent;parent = cur->_parent;}if (parent == NULL){return true;}//旋转调整if (parent->_bf == 2){if (cur->_bf == 1){RotateL(parent);}else if (cur->_bf == -1){RotateRL(parent);}}else{if (cur->_bf == 1){RotateLR(parent);}else if (cur->_bf == -1){RotateR(parent);}}}bool IsAVLTree(){int Height = 0;return _IsAVLTree(_root, Height);}void Inorder(){_Inorder(_root);cout << endl;}protected:void RotateR(Node* parent){Node* subL = parent->_left;Node* subLR = subL->_right;parent->_left = subLR;if (subLR){subLR->_parent = parent;}Node* ppNode = parent->_parent;subL->_right = parent;parent->_parent = subL;if (ppNode){if (ppNode->_left == parent){ppNode->_left = subL;}else{ppNode->_right = subL;subL->_parent = ppNode;}}else{subL->_parent = NULL;_root = subL;}subL->_bf = parent->_bf = 0;}void RotateL(Node* parent){Node* subR = parent->_right;Node* subRL = subR->_left;parent->_right = subRL;if (subRL){//subRL = subRL->_parent;subRL->_parent = parent;}Node* ppNode = parent->_parent;subR->_left = parent;parent->_parent = subR;if (ppNode){if (ppNode == parent){parent->_left = subR;}else{ppNode->_right = subR;subR->_parent = ppNode;}}else{subR->_parent = NULL;_root = subR;}subR->_bf = parent->_bf = 0;}void RotateRL(Node* parent){Node* subR = parent->_right;Node* subRL = subR->_left;int bf = subRL->_bf;RotateR(subR);RotateL(parent);if (bf == 0){subR->_bf = parent->_bf = 0;}else if (bf == 1){subR->_bf = 0;parent->_bf = -1;}else{subR->_bf = 1;parent->_bf = 0;}subR->_bf = 0;}void RotateLR(Node* parent){Node* subL = parent->_left;Node* subLR = subL->_right;int bf = subLR->_bf;RotateL(parent->_left);RotateR(parent);if (bf == 0){parent->_bf = subL->_bf = 0;subLR->_bf = 0; }else if (bf == -1){subL->_bf = 0;parent->_bf = 1;subLR->_bf = 0;}else{subL->_bf = 1;parent->_bf = 0;subLR->_bf = 0;}}int _Height(Node* root){if (root == NULL){return 0;}int left = _Height(root->_left) + 1;int right = _Height(root->_right) + 1;return left > right ? left : right;}bool _IsAVLTree(Node* root, int& Height){if (root == NULL);{int Height = 0;return true;}int LeftHeight = 0;if (_IsAVLTree(root->_left, LeftHeight) == false){return false;}int RightHeight = 0;if (_IsAVLTree(root->_right, RightHeight) == false){return false;}Height = LeftHeight > RightHeight ? LeftHeight + 1 : RightHeight + 1;return abs(LeftHeight - RightHeight) < 2;}void _Inorder(Node* root){if (root == NULL){return;}_Inorder(root->_left);cout << root->_key << ""<<endl;_Inorder(root->_right);}protected:Node* _root;};void test(){AVLTree<int, int> tree;int a[9] = { 16, 3, 7, 11, 9, 26, 18, 14, 15 };for (size_t i = 0; i < 9; ++i){tree.Insert(a[i], i);}tree.Inorder();cout << "IsAVLTree?" << tree.IsAVLTree() << "" << endl;}

0 0
原创粉丝点击