之前因为一些事情对二叉搜索树一直时很排斥,在网上学习视屏搞了红黑树的插入,但是具体的一些事情没有理解,这次我主要对avl树进行学习。并对所知道的东西进行整理。并且进行代码的时间
好了话不多说首先我先说明一些avl树的几个要代码部分转载至别人,删除部分最近会添加上。
- 左子树和右子树之间的差不能超过1.
- 任意的左子树和右子树之间也符合这个定律。
他们之间的差值时-1,0,1
具体的一些情况对于avl树而言它的插入主要分为四种情况,
还时用画图来解决把。
记住代码
typedef struct AvLtreeNode
{
int key;
AvLtreeNode* childleft;
AvLtreeNode* childright;
AvLtreeNode* parent;
int bf;
}AvlNode,*Avlptr;
void RotateR(Node* parent)
{
Node* SubL = parent->_left;
Node* SubLR = SubL->_right;
parent->_left = SubLR;
if (SubLR != NULL)
SubLR->_parent = parent;
//记录祖父节点以便一会判断
Node* Pparent = parent->_parent;
SubL->_right = parent;
parent->_parent = SubL;
if (Pparent == NULL)
_root = SubL;
else if (Pparent->_left == parent)
Pparent->_left = SubL;
else
Pparent->_right = SubL;
SubL->_parent = parent;
//调节平衡因子
parent->_bf = SubL->_bf = 0;
}
//parent->_right左旋转到parent的位置
void RotateL(Node* parent)
{
//若subrl不为空,则parent->left必不为空
Node* SubR = parent->_right;
Node* SubRL = SubR->_left;
parent->_right = SubRL;
if (SubRL != NULL)
SubRL->_parent = parent;
//记录祖父节点
Node* Pparent = parent->_parent;
SubR->_left = parent;
parent->_parent = SubR;
//判断祖父节点
if (Pparent == NULL)
{
_root = SubR;
SubR->_parent = NULL;
}
else if (Pparent->_left == parent)
Pparent->_left = SubR;
else
Pparent->_right = SubR;
SubR->_parent = Pparent;
//调节平衡因子
SubR->_bf = parent->_bf = 0;
}
bool Insert(const K& key, const V& value)
{
if (_root == NULL)
{
_root = new Node(key, value);
return true;
}
Node* parent = NULL;
Node* cur = _root;
while (cur)
{
if (key < cur->_key)
{
parent = cur;
cur = cur->_left;
}
else if (key > cur->_key)
{
parent = cur;
cur = cur->_right;
}
else
return false;
}
cur = new Node(key, value);
if (key < parent->_key)
parent->_left = cur;
else
parent->_right = cur;
cur->_parent = parent;
//调节平衡
while (parent)
{
if (cur == parent->_left)
parent->_bf -= 1;
else
parent->_bf += 1;
if (parent->_bf == 0)
return true;
else if (parent->_bf == -1
|| parent->_bf == 1)
{
cur = parent;
parent = cur->_parent;
}
else if (parent->_bf == -2
|| parent->_bf == 2)
{
if (parent->_bf == 2)
{
if (cur->_bf == 1)
RotateL(parent);
else
RotateRL(parent);
}
else
{
if (cur->_bf == -1)
RotateR(parent);
else
RotateLR(parent);
}
}
else
{
assert(false);
}
}
return true;
}
}
oid RotateLR(Node* parent)
{
Node* SubL = parent->_left;
Node* SubLR = SubL->_right;
int bf = SubLR->_bf;
RotateL(SubLR);
RotateR(parent);
if (bf == 1)
{
parent->_bf = SubLR->_bf = 0;
SubL->_bf = -1;
}
else if (bf == -1)
{
parent->_bf = 1;
SubLR->_bf = SubL->_bf = 0;
}
else if (bf == 0)
parent->_bf = SubL->_bf = SubLR->_bf = 0;
else
assert(false);
}
void RotateRL(Node* parent)
{
Node* SubR = parent->_right;
Node* SubRL = SubR->_left;
int bf = SubRL->_bf;
RotateR(SubR);
RotateL(parent);
if (bf == 1)
{
parent->_bf = -1;
SubR->_bf = SubRL->_bf = 0;
}
else if (bf == 1)
{
SubR->_bf = 1;
parent->_bf = SubRL->_bf = 0;
}
else if (bf == 0)
SubRL->_bf = SubR->_bf = parent->_bf = 0;
else
assert(false);
}
void print(Avlptr root)
{
if(root==NULL) return;
print(root->childleft);
printf("%d\n",root->key);
print(root->childright);
}
int main()
{
Avlptr root=NULL;
Insert(&root,10);
Insert(&root,20);
Insert(&root,15);
print(root->childright);
return 0;
}
删除也分三种情况
删除的是叶子节点
只有一个孩子节点
有两个孩子节点最先变化的节点为父节点
具体代码
todo