数据结构AVL树insert接口实现
Posted zhao111222333444
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构AVL树insert接口实现相关的知识,希望对你有一定的参考价值。
AVL树的插入接口需要分多种情况讨论,
前提是依据插入后平衡因子的值来做调整:
1.平衡因子为0,结束调整;
2.平衡因子为正负1,继续向上调整,直到0;
3.平衡因子为正负2,此时还需要进一步讨论:
出现平衡因子±2比较复杂,需要针对每一种情况做出不同旋转:
3.1. pParent的平衡因子为2,说明pParent的右子树高,设pParent的右子树的根为pSubR
当pSubR的平衡因子为1时,执行左单旋
当pSubR的平衡因子为-1时,执行右左双旋
3.2. pParent的平衡因子为-2,说明pParent的左子树高,设pParent的左子树的根为pSubL
当pSubL的平衡因子为-1是,执行右单旋
当pSubL的平衡因子为1时,执行左右双旋
旋转完成后,原pParent为根的子树个高度降低,已经平衡,不需要再向上更新。
#include<iostream>
using namespace std;
template<class T>
//AVLTree节点
class AVLNode
public:
//AVL数有3个节点指针,1个val,1个平衡因子
int _bf;
T _val;
AVLNode<T>* _partent;
AVLNode<T>* _left;
AVLNode<T>* _right;
AVLNode(const T& val = T())//类0值
:_bf(0)
, _val(val)
, _partent(nullptr)
, _left(nullptr)
, _right(nullptr)
;
//AVLTree树
template<class T>
class AVLTree
public:
typedef AVLNode<T> Node;
bool insert(const T& val)
//先判断是否为空树
if (_root == nullptr)
_root = new Node(val);
return true;
Node* node=_root;
Node* partent=nullptr;
while (node)
partent = node;
if (node->_val == val)
return false;
else if (node->_val > val)
node = node->_left;
else
node = node->_right;
//此时node在空上,并且没有链接父节点
node = new Node(val);
//此时链接父节点
if (partent->_val>val)
partent->_left = node;
else
partent->_right = node;
node->_partent = partent;
//开始调整bf
//从partent开始
while (partent)
//先对父节点bf进行增或减
if (partent->_left == node)
--partent->_bf;
else
++partent->_bf;
//根据调整后的bf操作
//bf==0,结束调整
//bf=+-1,继续向上更新
//bf=+-2,需要旋转
if (partent->_bf == 0)
break;
else if (partent->_bf == 1 || partent->_bf == -1)
node = partent;
partent = partent->_partent;
else if(abs(partent->_bf)==2)
if (node->_bf == -1 && partent->_bf == -2)
//需要右旋
RotateR(partent);
else if (node->_bf == 1 && partent->_bf == 2)
RotateL(partent);
else if (partent->_bf == 2 && node->_bf == -1)
Node* subRL = node->_left;
int bf = subRL->_bf;
RotateR(node);
RotateL(partent);
if (bf == 1)
partent->_bf = -1;
node->_bf = 0;
else if (bf == -1)
node->_bf = 1;
partent->_bf = 0;
else if (partent->_bf == -2 && node->_bf == 1)
Node* subLR = node->_right;
int bf = subLR->_bf;
RotateL(node);
RotateR(partent);
if (bf == 1)
partent->_bf = 0;
node->_bf = -1;
else if (bf == -1)
node->_bf = 0;
partent->_bf = 1;
break;
return true;
// partent subL
//subL -> partent
// subLR subLR
void RotateR(Node* partent)
Node* subL = partent->_left;
Node* subLR = subL->_right;
subL->_right = partent;
partent->_left = subLR;
if (subLR)
subLR->_partent = partent;
//调整上部节点
if (partent == _root)
_root = subL;
subL->_partent = nullptr;
else
Node* pparent = partent->_partent;
if (pparent->_left == partent)
pparent->_left = subL;
else
pparent->_right = subL;
subL->_partent = pparent;
partent->_partent = subL;
subL->_bf = partent->_bf = 0;
//partent subR
// subR -> partent
// subRL subRL
void RotateL(Node* partent)
Node* subR = partent->_right;
Node* subRL = subR->_left;
subR->_left = partent;
partent->_right = subRL;
if (subRL)
subRL->_partent = partent;
partent->_partent = subR;
//调整上部节点
if (partent == _root)
_root = subR;
subR->_partent = nullptr;
else
Node* pparent = partent->_partent;
if (pparent->_left == partent)
pparent->_left = subR;
else
pparent->_right = subR;
subR->_partent = pparent;
subR->_bf = partent->_bf = 0;
void _inorder(Node* root)
if (root)
_inorder(root->_left);
cout << root->_val << " ";
_inorder(root->_right);
void inorder()
return _inorder(_root);
//检查AVL是否正确
//查看节点长度
int Height(Node* root)
if (root == nullptr)
return 0;
int left = Height(root->_left);
int right = Height(root->_right);
return left > right ? left + 1 : right + 1;
bool _isbalance(Node* root)
if (root == nullptr)
return true;
int left = Height(root->_left);
int right = Height(root->_right);
if (right - left != root->_bf)
cout << root->_val <<":错误"<< endl;
return false;
return abs(root->_bf) < 2 && _isbalance(root->_left) && _isbalance(root->_right);
bool isbalance()
return _isbalance(_root);
private:
//记得置空
AVLNode<T>* _root=nullptr;
;
void test()
AVLTree<int> t;
t.insert(5);
t.insert(3);
t.insert(1);
t.insert(0);
t.insert(2);
t.insert(-1);
t.insert(5);
t.insert(1);
t.inorder();
cout << endl;
cout<<t.isbalance();
int main()
test();
system("pause");
return 0;
通过校验:
以上是关于数据结构AVL树insert接口实现的主要内容,如果未能解决你的问题,请参考以下文章