0%

数据结构平衡二叉树(AVL树)的删除

平衡二叉树是一棵带有平衡条件的二叉查找树,其删除操作是在二叉查找树的基础上添加平衡调整算法。

二叉查找树的删除操作参见博文:二叉查找树的删除(第七点)

先看一下示意图()

/二叉查找树的性质让我们可以很方便的查找最小最大键值/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/*查找最小键值节点:直接递归遍历左子树叶子节点*/
AvlNode* AvlTree::findMin(AvlNode *node)
{
if (NULL == node)
return NULL;

else if (NULL == node->leftchild)
return node;

else
return findMin(node->leftchild);

}

/*非递归实现查找最大键值节点*/
AvlNode* AvlTree::findMax(AvlNode *node)
{
if (node != NULL)
{
while (node->rightchild)
node = node->rightchild;
}

return node;

}

void AvlTree::Delete(int val)
{
if(NULL == Root)
return;
else
Delete(Root, val);
}

//节点的删除就是不断的交换数据,更改删除节点,最后定位到叶子节点
//
void AvlTree::Delete(AvlNode *&node, int val)
{
AvlNode *tempnode = NULL;
if(NULL == node)
return;

else if(val < node->data)
Delete(node->leftchild, val);
else if(val > node->data)
Delete(node->rightchild, val);

//find the val
else if(node->leftchild && node->rightchild)
{
tempnode = findMin(node->rightchild);
node->data = tempnode->data;
Delete(node->rightchild, node->data); //理解!待删除节点键值变换
} //此后要删除的键值节点不是val
else
{
if(node->leftchild && (NULL == node->rightchild))
{
tempnode = findMax(node->leftchild);
node->data = tempnode->data;
Delete(node->leftchild, node->data);
}
else if (node->rightchild && (NULL == node->leftchild))
{
tempnode = findMin(node->rightchild);
node->data = tempnode->data;
Delete(node->rightchild, node->data);
}
else
{
delete(node);
node = NULL;
}
}

if (node) //必须添加这个条件,利用递归的力量,调整平衡
{
//平衡判断
if (2 == Height(node->leftchild) - Height(node->rightchild))
{
//情况判断
if (Height(node->leftchild->leftchild) >= Height(node->leftchild->rightchild))
RotationLeftOnce(node);
else
{
RotationRightOnce(node->leftchild);
RotationLeftOnce(node);
}
}

if (2 == Height(node->rightchild) - Height(node->leftchild))
{
if (Height(node->rightchild->rightchild) >= Height(node->rightchild->leftchild))
RotationRightOnce(node);
else
{
RotationLeftOnce(node->rightchild);
RotationRightOnce(node);
}
}
}

}

上面的删除操作具体参见:二叉查找树的删除,另外平衡二叉树的查找,遍历与二叉查找树一样。

上面的删除操作具体参见:二叉查找树的删除,另外平衡二叉树的查找,遍历与二叉查找树一样。

二、清空二叉树(析构函数)

1
2
3
4
5
6
7
8
9
10
void AvlTree::MakeEmpty(AvlNode *&node)
{
if (node)
{
MakeEmpty(node->leftchild);
MakeEmpty(node->rightchild);
delete node;
}
node = NULL;
}

三、平衡二叉树时间复杂度分析
平衡二叉树在二叉查找树的基础上添加了旋转算法,但是旋转操作仅仅改变少数指针的指向,耗费常数时间,平衡二叉树加入了平衡机制,所以其深度为logN,查找、插入和删除在平均和最坏情况下都是O(logN)。对比二叉查找树,时间上稳定了很多。