AVL树插入小结
来源:互联网 发布:utorrent linux 64位 编辑:程序博客网 时间:2024/06/06 06:49
一棵AVL树或者是空树,或者是具有以下性质的二叉搜索树:
1. 它的左右子树都是AVL树
2. 左子树和右子树高度之差(简称平衡因子)的绝对值不超过1(-1、0、1)
如果一棵二叉搜索树是高度平衡的,它就是AVL树。如果它有n个结点,其高度可保持在O(lgn),平均搜索时间复杂度O(lg(n))
在二叉搜索树中,我们知道要插入一个元素,必须将他插到合适的位置,但是在AVL树中,不仅要插入到合适的位置,还要保证插入该元素之后这棵树是平衡搜索二叉树。
关于如何调整一棵二叉树为平衡二叉树,这里就涉及到四种旋转:
左单旋,右单旋,左右双旋,右左双旋。
下边就每一种旋转都给出图示:
这是需要左单旋的情况
这是需要右单旋的情况
这是需要右左双旋的情况
这是需要左右双旋的情况
代码如下
#include<iostream>using namespace std;template<class K,class V>struct AVLTreeNode{ AVLTreeNode(const K &key, const V &value) :_key(key) , _value(value) , _pLeft(nullptr) , _pRight(nullptr) , _pParent(nullptr) , _bf(0) {} AVLTreeNode<K, V> *_pLeft; AVLTreeNode<K, V> *_pRight; AVLTreeNode<K, V> *_pParent; K _key; V _value; int _bf;};template<class K,class V>class AVLTree{private: typedef AVLTreeNode<K, V> Node;public: AVLTree() :_pRoot(nullptr) {} void InOrder() { cout << "InOrder:" << endl; _InOrder(_pRoot); cout << endl; } void Insert(const K &key, const V &value) { _Insert(_pRoot, key, value); } bool IsBalanceTree() { return _IsBalanceTree(_pRoot); }private: bool _Insert(Node *pRoot, const K &key, const V &value) { if (nullptr == pRoot) { _pRoot = new Node(key, value); return true; } Node *pCur = pRoot; Node *parent = nullptr; while (pCur) { if (key < pCur->_key) { parent = pCur; pCur = pCur->_pLeft; } else if (key > pCur->_key) { parent = pCur; pCur = pCur->_pRight; } else { return false; } } pCur = new Node(key, value); if (key < parent->_key) parent->_pLeft = pCur; else parent->_pRight = pCur; pCur->_pParent = parent; if (pCur == parent->_pLeft) --parent->_bf; else ++parent->_bf; while (nullptr != parent) { if (0==parent->_bf) return true; else if (1 == parent->_bf || -1 == parent->_bf) { Node *ppParent = parent->_pParent; if (nullptr != ppParent) { if (ppParent->_pLeft == parent) ppParent->_bf--; else ppParent->_bf++; } parent = parent->_pParent; } else { if (2 == parent->_bf) { if (1 == parent->_pRight->_bf) _RotateL(parent); else _RotateRL(parent); } else { if (-1 == parent->_pLeft->_bf) _RotateR(parent); else _RotateLR(parent); } break; } } return true; } void _InOrder(Node *pRoot) { if (pRoot) { _InOrder(pRoot->_pLeft); cout << pRoot->_key << " "; _InOrder(pRoot->_pRight); } } void _RotateL(Node *parent) { Node *pSubR = parent->_pRight; Node *ppParent = parent ->_pParent; Node *pSubRL = pSubR->_pLeft; parent->_pRight = pSubRL; if (nullptr != pSubRL) pSubRL->_pParent = parent; pSubR->_pLeft = parent; parent->_pParent = pSubR; if (nullptr == ppParent) { _pRoot = pSubR; pSubR->_pParent = nullptr; } else { if (parent == ppParent->_pLeft) ppParent->_pLeft=pSubR; else ppParent->_pRight=pSubR; pSubR->_pParent = ppParent; } parent->_bf = pSubR->_bf = 0; parent = pSubR; } void _RotateR(Node *parent) { Node *pSubL = parent->_pLeft; Node *pSubLR = pSubL->_pRight; Node *ppParent = parent->_pParent; parent->_pLeft = pSubLR; if (pSubLR) pSubLR->_pParent = parent; pSubL->_pRight = parent; parent->_pParent = pSubL; if (nullptr == ppParent) { _pRoot = pSubL; pSubL->_pParent = nullptr; } else { if (parent == ppParent->_pLeft) ppParent->_pLeft = pSubL; else ppParent->_pRight = pSubL; pSubL->_pParent = ppParent; } pSubL->_bf = parent->_bf = 0; parent = pSubL; } void _RotateRL(Node *parent) { Node *pSubR = parent->_pRight; Node *pSubRL = pSubR->_pLeft; int SubRLf = pSubRL->_bf; _RotateR(parent->_pRight); _RotateL(parent); if (1 == SubRLf) parent->_bf = -1; else if (-1 == SubRLf) pSubR->_bf = 1; } void _RotateLR(Node *parent) { Node *pSubL = parent->_pLeft; Node *pSubLR = pSubL->_pRight; int SubLRf = pSubLR->_bf; _RotateL(parent->_pLeft); _RotateR(parent); if (-1 == SubLRf) parent->_bf = 1; else if (1 == SubLRf) pSubL->_bf = -1; } size_t _Height(Node *pRoot) { if (nullptr == pRoot) return 0; if (nullptr == pRoot->_pLeft&&nullptr == pRoot) return 1; size_t leftHeight = _Height(pRoot->_pLeft); size_t rightHeight = _Height(pRoot->_pRight); return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1; } bool _IsBalanceTree(Node *pRoot) { if (pRoot == nullptr) return true; int leftHeight = _Height(pRoot->_pLeft); int rightHeight = _Height(pRoot->_pRight); if (rightHeight - leftHeight != pRoot->_bf) { cout << "平衡因子错误" << endl; return false; } return (abs(leftHeight - rightHeight) <2)&&_IsBalanceTree(pRoot->_pLeft)&&_IsBalanceTree(pRoot->_pRight); }private: Node *_pRoot;};void test1(){ int a[10] = { 3, 2, 1, 4, 5, 6, 7, 10, 9, 8 }; AVLTree<int, int> avl; for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++) avl.Insert(a[i], a[i]); cout << avl.IsBalanceTree() << endl; avl.InOrder();}void test2(){ int array2[] = { 4, 2, 6, 1, 3, 5, 15, 7, 16, 14 }; AVLTree<int, int> avl; for (int i = 0; i < sizeof(array2) / sizeof(array2[0]); i++) avl.Insert(array2[i], array2[i]); cout << avl.IsBalanceTree() << endl; avl.InOrder();}void test3(){ int array1[] = { 16, 3, 7, 11, 9, 26, 18, 14, 15 }; AVLTree<int, int> avl; for (int i = 0; i < sizeof(array1) / sizeof(array1[0]); i++) avl.Insert(array1[i], array1[i]); cout << avl.IsBalanceTree() << endl; avl.InOrder();}int main(){ test1(); test2(); test3(); system("pause");}
阅读全文
1 0
- AVL树插入小结
- AVL树小结
- AVL树插入算法
- AVL树插入删除
- 算法-AVL树的插入
- AVL树的插入操作
- AVL树的插入算法
- AVL树实现(插入删除)
- 【AVL树】AVL树的插入操作以及旋转
- 平衡二叉树(AVL树)小结
- 平衡二叉树(AVL树)小结
- AVL树的插入删除分析
- AVL树插入和删除源代码
- AVL树的插入、删除、旋转
- AVL树的查找,插入,删除
- AVL 树的插入与旋转
- AVL树的插入与删除
- AVL树插入的简单实现
- 2017-05-22 IT杂谈,读《决断力》笔记
- Unity3d中的Tcp socket通信(开源)
- 排序算法
- 欢迎使用CSDN-markdown编辑器
- bootStrap学习10---- 表单
- AVL树插入小结
- 实用计算机视觉 -- 简单摄像机针孔模型
- Kotlin编程之AndroidStudio(包括3.0与2.x版本)配置与使用
- vue2.0与express构建淘票票页面
- GRE零基础50-60天出分随感--V159 Q170
- 使用Lucene开发简单的站内新闻搜索引擎(索引库的创建)
- HCRM医院客户管理系统
- 面试笔试准备(1)
- 使用 vue2+Vuex+Router 重写饿了么点餐系统和 vue 插件简析