【数据结构】搜索结构之AVL树
2018-03-05 22:06
169 查看
AVL树———又称平衡二叉树
二插搜索树虽然可以缩短查找效率,但如果数据有序或接近有序二插搜索树将退化为单支树,查找元素相当于在顺序表中搜索元素,效率低下。
AVL树概念:
平衡化旋转
如果在一棵原本是平衡的二插搜索树中插入一个新节点,可能造成不平衡,此时必须调整输的结构,使之平衡化。
1.左单旋:
插入点位于ptr的右子结点的右子树—-右右
2.右单旋:
插入点位于ptr的左子结点的左子树—-左左
3.先左后右双旋:
插入点位于ptr左子节点的右子树—-左右
4.先右后左双旋:
插入点位于ptr右子节点的左子树—-右左
AVL树的插入
AVL树的删除
AVL树代码:
【AVLTree.h】
【test.cpp】
二插搜索树虽然可以缩短查找效率,但如果数据有序或接近有序二插搜索树将退化为单支树,查找元素相当于在顺序表中搜索元素,效率低下。
AVL树概念:
平衡化旋转
如果在一棵原本是平衡的二插搜索树中插入一个新节点,可能造成不平衡,此时必须调整输的结构,使之平衡化。
1.左单旋:
插入点位于ptr的右子结点的右子树—-右右
2.右单旋:
插入点位于ptr的左子结点的左子树—-左左
3.先左后右双旋:
插入点位于ptr左子节点的右子树—-左右
4.先右后左双旋:
插入点位于ptr右子节点的左子树—-右左
AVL树的插入
AVL树的删除
AVL树代码:
【AVLTree.h】
#pragma once #include<iostream> using namespace std; template<class K,class V> struct AVLNode { AVLNode(K key,V value) :_Lchild(NULL) , _Rchild(NULL) , _parent(NULL) , _key(key) , _value(value) , _bf(0) {} AVLNode<K, V>* _Lchild; AVLNode<K, V>* _Rchild; AVLNode<K, V>* _parent; K _key; V _value; int _bf; }; template<class K,class V> class AVLTree { typedef AVLNode<K, V>* pNode; typedef AVLNode<K, V> Node; public: AVLTree() :Root(NULL) {} bool Insert(K& k,V& v) //插入元素 { return _Insert(k, v); } void InOrder() //中序遍历 { _InOrder(Root); } bool CheckAVLT() //判断是否是AVL树 { return _CheckAVLT(Root); } ///////////////////////////////////////////////////////////// private: bool _CheckAVLT(pNode pRoot) { if (pRoot) { int len = _Height(pRoot->_Rchild) - _Height(pRoot->_Lchild); if (len<-1 || len>1) return false; _CheckAVLT(pRoot->_Lchild); _CheckAVLT(pRoot->_Rchild); } return true; } int _Height(pNode pRoot) { if (pRoot == NULL) return 0; return _Height(pRoot->_Lchild) > _Height(pRoot->_Rchild) ? _Height(pRoot->_Lchild) + 1 : _Height(pRoot->_Rchild) + 1; } void _InOrder(pNode pRoot) { if (pRoot != NULL) { _InOrder(pRoot->_Lchild); cout << "<" << pRoot->_key << "," << pRoot->_value << ">" << endl; _InOrder(pRoot->_Rchild); } } bool _Insert(K& k, V& v) { pNode newNode = new Node(k, v); if (Root == NULL) { Root = newNode; return true; } pNode cur = Root; pNode pParent = NULL; while (cur) //查找要插入的位置 { pParent = cur; if (cur->_key > k) cur = cur->_Lchild; else if (cur->_key < k) cur = cur->_Rchild; else return false; } if (pParent->_key>k) { pParent->_Lchild = newNode; newNode->_parent = pParent; } else if (pParent->_key < k) { pParent->_Rchild = newNode; newNode->_parent = pParent; } cur = newNode; //cur标记双亲节点的孩子 while (pParent) { if (pParent->_Lchild == cur) pParent->_bf--; else if (pParent->_Rchild == cur) pParent->_bf++; if (pParent->_bf == 1 || pParent->_bf == -1) { cur = pParent; pParent = pParent->_parent; } else if (pParent->_bf == 2 || pParent->_bf == -2) //旋转 { if (pParent->_bf == 2) { if (pParent->_Rchild->_bf==1) RotateL(pParent); //左单旋 else RotateRL(pParent); //右左双旋 } else { if (pParent->_Lchild->_bf == -1) RotateR(pParent); //右单旋 else RotateLR(pParent); //左右双旋 } } else break; } return true; } void RotateL(pNode pParent) //左单旋 { pNode pSubR = pParent->_Rchild; pNode pSubRL = pSubR->_Lchild; pNode _pParent = pParent->_parent; pParent->_Rchild = pSubRL; if (pSubRL!=NULL) pSubRL->_parent = pParent; pSubR->_Lchild = pParent; pParent->_parent = pSubR; if (_pParent == NULL) { Root = pSubR; pSubR->_parent = _pParent; } else if (_pParent != NULL&&_pParent->_Lchild == pParent) { _pParent->_Lchild = pSubR; pSubR->_parent = _pParent; } else if (_pParent != NULL&&_pParent->_Rchild == pParent) { _pParent->_Rchild = pSubR; pSubR->_parent = _pParent; } pSubR->_bf = 0; pParent->_bf = 0; } void RotateR(pNode pParent) //右单旋 { pNode pSubL = pParent->_Lchild; pNode pSubLR = pSubL->_Rchild; pNode _pParent = pParent->_parent; pParent->_Lchild = pSubLR; if (pSubLR!=NULL) pSubLR->_parent = pParent; pSubL->_Rchild = pParent; pParent->_parent = pSubL; if (_pParent == NULL) { Root = pSubL; pSubL->_parent = _pParent; } else if (_pParent != NULL&&_pParent->_Lchild == pParent) { _pParent->_Lchild = pSubL; pSubL->_parent = _pParent; } else if (_pParent != NULL&&_pParent->_Rchild == pParent) { _pParent->_Rchild = pSubL; pSubL->_parent = _pParent; } pSubL->_bf = 0; pParent->_bf = 0; } void RotateRL(pNode pnode) //右左双旋 { pNode pParent = pnode; pNode pSubR = pnode->_Rchild; RotateR(pnode->_Rchild); RotateL(pnode); if (pSubR->_Lchild->_bf== 1) { pParent->_bf = -1; } else if (pSubR->_Lchild->_bf == -1) { pSubR->_bf = 1; } } void RotateLR(pNode pnode) //左右双旋 { pNode pParent = pnode; pNode pSubL= pnode->_Lchild; RotateL(pnode->_Lchild); RotateR(pnode); if (pSubL->_Rchild->_bf == -1) { pParent->_bf = 1; } else if (pSubL->_Rchild->_bf == 1) { pSubL->_bf = -1; } } private: pNode Root; }; void test() { //int arr[] = {5,3,4,1,7,8,2,6,0,9}; //普通版 //int arr[] = {30,20,50,40,60,70}; //左单旋 //int arr[] = {60,40,70,30,50,20}; //右单旋 //int arr[] = { 3, 2, 6, 5, 4, 7 }; //右左双旋 int arr[] = {4,2,6,1,3,5,15,7,16,14}; //左右双旋 int size = sizeof(arr) / sizeof(arr[0]); AVLTree<int, int> t; for (int i = 0; i < size; i++) { t.Insert(arr[i], i); } t.InOrder(); if (t.CheckAVLT()) cout << "是平衡二叉树" << endl; else cout << "不是平衡二叉树" << endl; }
【test.cpp】
#include"AVLTree.h" int main() { test(); system("pause"); return 0; }
相关文章推荐
- 数据结构-平衡搜索二叉树(AVL树)
- 算法基础知识科普:8大搜索算法之AVL树(上)
- 数据结构之三元组顺序表实现稀疏矩阵运算(参考整理严蔚敏数据结构)
- 数据结构例程——图的邻接矩阵存储结构及算法
- 【算法和数据结构】_9_线性结构_队列_续_1
- 数据结构学习小结(1)-----线性结构-----线性表
- 《数据结构》第三章知识结构导图
- opencv数据结构-MAT结构详解
- 数据结构_ST算法+二分搜索_GCD问题
- [数据结构]02-线性结构2 一元多项式的乘法与加法运算
- 数据结构之线性结构---队列 顺序储存
- 数据结构之线性结构--双向循环链表
- 《数据结构》第二章 线性表 知识结构导图——信管1133-09
- 数据结构学习笔记之图结构
- Java数据结构与算法之数据结构-逻辑结构-集合(七)------集合之Set接口和HashSet和TreeSet、LinkedHashSet实现类总结
- 数据结构之有向网邻接表实现拓扑与关键活动(参考整理严蔚敏数据结构)
- 序列与结构数据库-序列相似性搜索
- 考研笔记数据结构线性结构之C语言
- 数据结构线性表各种结构代码实现(C语言)
- 【数据结构】平衡二叉树之AVL树