visualgo.net BST AVL
1. 二叉查找树
二叉查找树(Binary Search Tree),又被称为二叉搜索树
1. 特点
- 任意节点的左子树不空, 则左子树上所有节点的key均小于它的根节点的key
- 任意节点的右子树不空, 则右子树上所有节点的key均大于它的根节点的key
- 任意节点的左,右子树也分别为二叉查找树
- 没有key相等的节点
二叉查找树进行中序遍历,可以得到一个递增的有序序列
2. 结构
二叉搜索树通常使用链式存储孩子表示法。
struct Node {
int key;
struct Node* left;
struct Node* right;
}
3. 操作
3.1 插入
- 如果二叉查找树为空,则直接插入。
- 如果插入节点key小于根结点key,则插入到左子树中;大于根结点key,则插入到右子树中。
- 依次类推,直到找到插入位置。
BST默认插入新的节点是叶子节点。
Node* Insert(Node*& node, int key){
if(NULL == node) node = new Node(key);
if (key < node->key) node->left = Insert(node->left, key);
else if (key > node->key) node->right = Insert(node->right,key);
return node;
}
3.2 查找
- 查找指定key的节点
从根结点开始,若二叉树非空,将给定值与根结点的关键字比较,若相等,则查找成功;若不等,则当给定值小于根结点关键字时,在根结点的左子树中查找,否则在根结点的右子树中查找。Node* Search(Node* node, int key){ if(NULL == node) return NULL; if (key < node->key) return Search(node->left, key); else if (key > node->key) return Search(node->right, key); return node; }
- 查找最大/最小key的节点
// 最大键 Node* Maximum(Node* node){ if (NULL == node) return NULL; while (NULL != node->right) node = node->right; return node; } // 最小键 Node* Minimum(Node* node){ if (NULL == node) return NULL; while (NULL != node->left) node = node->left; return node; }
3.3 删除
二叉查找树的删除操作是相对复杂一点,它要按 3 种情况来处理:
-
被删除结点是叶子结点,直接删除。
-
结点只有左子树或只有右子树,则让子树替代;
-
结点既有左子树,又有右子树,有两种处理方式
替代删除,后继代替删除节点,然后删除后继;或者前驱代替删除节点,然后删除前驱。
合并删除,右子树合并到左子树的最大值的右子树上;或者左子树合并到右子树最小值的左子树上。
Node* Remove(Node* node, int key){
if(NULL == node) return NULL;
if (key < node->key) node->left = Remove(node->left, key);
else if (key > node->key) node->right = Remove(node->right, key);
else {
if(NULL != node->right && NULL != node->left){// 有两个子树
// 最小值删除
Node* p = Minimum(node->right);
node->key = p->key;
node->right = Remove(node->right,p->key);
} else {// 叶子节点或者只有一个子树
Node* res = NULL;
if(NULL != node->right) res = node->right;
if(NULL != node->left) res = node->left;
delete node;
node = NULL;
return res;
}
}
return node;
}
优缺点
- 优点
No. | 操作 | 时间复杂度 |
---|---|---|
1 | 插入 | O(log n) |
2 | 查找 | O(log n) |
3 | 插入 | O(log n) |
- 缺点
二叉搜索树构造顺序影响操作的时间复杂度。
参考代码
#include
#include
using namespace std;
// 节点
struct Node{
int key; ///< 键
Node *left; ///< 左子节点
Node *right; ///< 右子节点
Node(int key)
:key(key),left(NULL),right(NULL){}
};
// 辅助操作
Node* Maximum(Node* node){
if (NULL == node) return NULL;
while (NULL != node->right) node = node->right;
return node;
}
Node* Minimum(Node* node){
if (NULL == node) return NULL;
while (NULL != node->left) node = node->left;
return node;
}
// 核心操作
Node* Insert(Node*& node, int key){
if(NULL == node) node = new Node(key);
if (key < node->key) node->left = Insert(node->left, key);
else if (key > node->key) node->right = Insert(node->right,key);
return node;
}
Node* Search(Node* node, int key){
if(NULL == node) return NULL;
if (key < node->key) return Search(node->left, key);
else if (key > node->key) return Search(node->right, key);
return node;
}
Node* Remove(Node* node, int key){
if(NULL == node) return NULL;
if (key < node->key) node->left = Remove(node->left, key);
else if (key > node->key) node->right = Remove(node->right, key);
else {
if(NULL != node->right && NULL != node->left){// 有两个子树
// 最小值删除
Node* p = Minimum(node->right);
node->key = p->key;
node->right = Remove(node->right,p->key);
} else {// 叶子节点或者只有一个子树
Node* res = NULL;
if(NULL != node->right) res = node->right;
if(NULL != node->left) res = node->left;
delete node;
node = NULL;
return res;
}
}
return node;
}
/////////////////////////////////////////////////////////////
ostream& operator<<(ostream& os,const Node root) {
queue q;
q.push(&root);
while(!q.empty()){
const Node* curr = q.front();
q.pop();
if (NULL != curr){
os << curr->key;
q.push(curr->left);
q.push(curr->right);
} else {
os << '#';
}
}
return os;
}
void TestInsert(Node*& root){
Insert(root,1);
Insert(root,2);
Insert(root,3);
Insert(root,4);
Insert(root,5);
cout << *root << endl;
}
void TestSearch(Node* root,int key){
cout <<"Search " << key << ":" << Search(root,key) << endl;
}
void TestRemove(Node*& root,int key){
root = Remove(root, key);
cout <<"Remove " << key << ":" ;
if(NULL != root) cout << *root << endl;
else cout << "#" << endl;
}
void TestMax(Node* root){
Node* maxNode = Maximum(root);
cout << "Max:"<< maxNode->key <<":"<< maxNode <key <<":"<< minNode <
2. AVL树(平衡二叉树)
BST树的缺点不平衡
平衡二叉树/自平衡二叉查找树(Balanced Binary Tree): 也称为AVL树(名称来自发明人G.M. Adelson-Velsky 和 E.M. Landis的首字母),它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
特点
- 左右子树深度之差的绝对值不超过1(任意节点的两子树的高度最大差别为1).
- 左右子树仍然为平衡二叉树.
- 平衡因子BF(Balance Factor):左树深度减去右树深度的值。平衡因子BF = 左子树深度-右子树深度。
- 平衡二叉树每个结点的平衡因子只能是1,0,-1。若其绝对值超过1,则该二叉排序树就是不平衡的。当BF为-1、0、1时,二叉树平衡;反之,不平衡。
树快速查找的关键是高度要低,高度低的关键是平衡。
判断平衡:BF
/* 节点 */
struct Node{
char key; // 键值
Node* right; // 右节点
Node* left; // 左节点
int height; // 节点高度
Node(char key):key(key),right(NULL),left(NULL),height(0){}
Node(char key,int height):key(key),right(NULL),left(NULL),height(height){}
};
/*
* 平衡因子:左子树树高-右子树树高
*/
int BalanceFactor(const Node* root){
if(NULL == root) return 0;
if(NULL == root->left && NULL == root->right) return 0;
if(NULL == root->left) return -root->right->height;
if(NULL == root->right) return root->left->height;
return root->left->height - root->right->height;
}
ostream& operator<<(ostream& os,const Node root) {
queue q;
q.push(&root);
while(!q.empty()){
const Node* curr = q.front();
q.pop();
if (NULL != curr){
os << curr->key << "[" << BalanceFactor(curr)<<"]";
q.push(curr->left);
q.push(curr->right);
} else {
os << '#';
}
}
return os;
}
int main(){
{
// 1
// /
// 2
// /
// 3
Node a('1',3);
Node b('2',2);
Node c('3',1);
a.left = &b;
b.left = &c;
cout << a << endl;
}
{
// 1
// \
// 2
// \
// 3
Node a('1',3);
Node b('2',2);
Node c('3',1);
a.right = &b;
b.right = &c;
cout << a << endl;
}
{
// 1
// /
// 2
// \
// 3
Node a('1', 3);
Node b('2', 2);
Node c('3', 1);
a.left = &b;
b.right = &c;
cout << a << endl;
}
{
// 1
// \
// 2
// /
// 3
Node a('1', 3);
Node b('2', 2);
Node c('3', 1);
a.right = &b;
b.left = &c;
cout << a << endl;
}
}
LeetCode 110. 平衡二叉树
两种旋转(左旋/右旋)、三个节点(新插入节点/不平衡节点/旋转节点)、四种不平衡(LL/RR/RL/LR)。
操作
AVL树的操作基本和二叉查找树一样,这里我们关注的是两个变化很大的操作:插入和删除!
旋转
旋转条件:当最小不平衡子树根节点BF>1,右旋;BF<-1,左旋。
旋转步骤:
- 获取旋转节点
- 旋转节点的子节点替换父节点的旋转节点
- 旋转节点父节点做旋转节点子节点
- 返回旋转节点
#include
#include
using namespace std;
/* 节点 */
struct Node{
char key; // 键值
Node* right; // 右节点
Node* left; // 左节点
int height; // 节点高度
Node(char key):key(key),right(NULL),left(NULL),height(0){}
};
ostream& operator<<(ostream& os,const Node root) {
queue q;
q.push(&root);
while(!q.empty()){
const Node* curr = q.front();
q.pop();
if (NULL != curr){
os << curr->key;
q.push(curr->left);
q.push(curr->right);
} else {
os << '#';
}
}
return os;
}
/*
* 右旋
* Q P
* / \ / \
* P C -------> A Q
* / \ / / \
* A B X' B C
*
*/
Node* RightRotate(Node* root){
Node* pivot = root->left; // 获取旋转节点
root->left = pivot->right; // 旋转节点的子节点替换父节点的旋转节点
pivot->right = root; // 旋转节点父节点做旋转节点子节点
return pivot; // 返回旋转节点
}
/*
* 左旋
* P Q
* / \ / \
* A Q -----> P C
* / \ / \ \
* B C A B X'
*/
Node* LeftRotate(Node* root){
Node* pivot = root->right; // 获取旋转节点
root->right = pivot->left; // 旋转节点的子节点替换父节点的旋转节点
pivot->left = root; // 旋转节点父节点做旋转节点子节点
return pivot; // 返回旋转节点
}
int main(){
{
Node a('1');
Node b('2');
Node c('3');
a.left = &b;
b.left = &c;
cout << a << endl;
cout << *RightRotate(&a) << endl;
}
{
Node a('1');
Node b('2');
Node c('3');
a.right = &b;
b.right = &c;
cout << a << endl;
cout << *LeftRotate(&a) << endl;
}
{
Node q('Q');
Node p('P');
Node c('C');
Node a('A');
Node b('B');
q.left = &p;
q.right = &c;
p.left = &a;
p.right = &b;
cout << q << endl;
Node* r = RightRotate(&q);
cout << *r << endl;
Node *l = LeftRotate(r);
cout << *l << endl;
}
}
四种不平衡
不平衡的四种情况:
LL:插入一个新节点到不平衡节点的左子树(Left)的左子树(Left),导致不平衡节点的平衡因子由1变为2
RR:插入一个新节点到不平衡节点的右子树(Right)的右子树(Right),导致不平衡节点的平衡因子由-1变为-2
LR:插入一个新节点到不平衡节点的左子树(Left)的右子树(Right),导致不平衡节点的平衡因子由1变为2
RL:插入一个新节点到不平衡节点的右子树(Right)的左子树(Left),导致不平衡节点的平衡因子由-1变为-2
/*
* 检查是否平衡
*/
void Check(Node* root){
int nf = BalanceFactor(root);
if(nf>1){
int lf = BalanceFactor(root->left);
if(lf > 0) { // LL
cout << "LL" << endl;
} else { // LR
cout << "LR" << endl;
}
}else if(nf < -1){
int rf = BalanceFactor(root->right);
if (rf < 0) { // RR
cout << "RR" << endl;
} else { // RL
cout << "RL" << endl;
}
}else{// 保持平衡的情况
cout << "Balance" << endl;
}
}
int main(){
{
// 1
// /
// 2
// /
// 3
Node a('1',3);
Node b('2',2);
Node c('3',1);
a.left = &b;
b.left = &c;
cout << a << endl;
Check(&a);
}
{
// 1
// \
// 2
// \
// 3
Node a('1',3);
Node b('2',2);
Node c('3',1);
a.right = &b;
b.right = &c;
cout << a << endl;
Check(&a);
}
{
// 1
// /
// 2
// \
// 3
Node a('1', 3);
Node b('2', 2);
Node c('3', 1);
a.left = &b;
b.right = &c;
cout << a << endl;
Check(&a);
}
{
// 1
// \
// 2
// /
// 3
Node a('1', 3);
Node b('2', 2);
Node c('3', 1);
a.right = &b;
b.left = &c;
cout << a << endl;
Check(&a);
}
{
// 1
// / \
// 2 4
// / \
// 3 5
Node a('1', 3);
Node b('2', 2);
Node c('3', 1);
Node d('4', 1);
Node e('5', 1);
a.left = &b;
a.right = &d;
b.left = &c;
b.right = &e;
cout << a << endl;
Check(&a);
}
{
// 1
// / \
// 4 2
// / \
// 5 3
Node a('1', 3);
Node b('2', 2);
Node c('3', 1);
Node d('4', 1);
Node e('5', 1);
a.right = &b;
a.left = &d;
b.right = &c;
b.left = &e;
cout << a << endl;
Check(&a);
}
{
// 1
// / \
// 2 4
// / \
// 3 5
// /
// 6
Node a('1', 4);
Node b('2', 3);
Node c('3', 2);
Node d('4', 1);
Node e('5', 1);
Node f('6', 1);
a.left = &b;
a.right = &d;
b.left = &c;
b.right = &e;
c.left = &f;
cout << a << endl;
Check(&a);
}
{
// 1
// / \
// 2 4
// / \
// 3 5
// \
// 6
Node a('1', 4);
Node b('2', 3);
Node c('3', 2);
Node d('4', 1);
Node e('5', 1);
Node f('6', 1);
a.left = &b;
a.right = &d;
b.left = &c;
b.right = &e;
c.right = &f;
cout << a << endl;
Check(&a);
}
{
// 1
// / \
// 2 4
// / \
// 3 5
// /
// 6
Node a('1', 4);
Node b('2', 3);
Node c('3', 1);
Node d('4', 1);
Node e('5', 2);
Node f('6', 1);
a.left = &b;
a.right = &d;
b.left = &c;
b.right = &e;
e.left = &f;
cout << a << endl;
Check(&a);
}
{
// 1
// / \
// 2 4
// / \
// 3 5
// \
// 6
Node a('1', 4);
Node b('2', 3);
Node c('3', 1);
Node d('4', 1);
Node e('5', 2);
Node f('6', 1);
a.left = &b;
a.right = &d;
b.left = &c;
b.right = &e;
e.right = &f;
cout << a << endl;
Check(&a);
}
{
// 1
// / \
// 4 2
// / \
// 5 3
// /
// 6
Node a('1', 3);
Node b('2', 2);
Node c('3', 1);
Node d('4', 1);
Node e('5', 1);
Node f('6', 1);
a.right = &b;
a.left = &d;
b.right = &c;
b.left = &e;
e.left = &f;
cout << a << endl;
Check(&a);
}
}
不平衡处理方法
- 单向右旋平衡处理LL
- 单向左旋平衡处理RR
- 双向旋转(先左后右)平衡处理LR
- 双向旋转(先右后左)平衡处理RL
/*
* 平衡
*/
Node* Balance(Node* root){
Node *res = root;
int nf = BalanceFactor(root);
if(nf>1){
int lf = BalanceFactor(root->left);
if(lf > 0) { // LL
cout << "LL" << endl;
res = RightRotate(root);
} else { // LR
cout << "LR" << endl;
root->left = LeftRotate(root->left);
res = RightRotate(root);
}
}else if(nf <-1){
int rf = BalanceFactor(root->right);
if (rf < 0) { // RR
cout << "RR" << endl;
res = LeftRotate(root);
} else { // RL
cout << "RL" << endl;
root->right = RightRotate(root->right);
res = LeftRotate(root);
}
}else{
cout << "Balance" << endl;
// 保持平衡的情况
}
return res;
}
int main(){
{
// 1
// /
// 2
// /
// 3
Node a('1',3);
Node b('2',2);
Node c('3',1);
a.left = &b;
b.left = &c;
cout << a << endl;
Check(&a);
cout << *Balance(&a) << endl;
cout << "----------------" << endl;
}
{
// 1
// \
// 2
// \
// 3
Node a('1',3);
Node b('2',2);
Node c('3',1);
a.right = &b;
b.right = &c;
cout << a << endl;
Check(&a);
cout << *Balance(&a) << endl;
cout << "----------------" << endl;
}
{
// 1
// /
// 2
// \
// 3
Node a('1', 3);
Node b('2', 2);
Node c('3', 1);
a.left = &b;
b.right = &c;
cout << a << endl;
Check(&a);
cout << *Balance(&a) << endl;
cout << "----------------" << endl;
}
{
// 1
// \
// 2
// /
// 3
Node a('1', 3);
Node b('2', 2);
Node c('3', 1);
a.right = &b;
b.left = &c;
cout << a << endl;
Check(&a);
cout << *Balance(&a) << endl;
cout << "----------------" << endl;
}
{
// 1
// / \
// 2 4
// / \
// 3 5
Node a('1', 3);
Node b('2', 2);
Node c('3', 1);
Node d('4', 1);
Node e('5', 1);
a.left = &b;
a.right = &d;
b.left = &c;
b.right = &e;
cout << a << endl;
Check(&a);
cout << *Balance(&a) << endl;
cout << "----------------" << endl;
}
{
// 1
// / \
// 4 2
// / \
// 5 3
Node a('1', 3);
Node b('2', 2);
Node c('3', 1);
Node d('4', 1);
Node e('5', 1);
a.right = &b;
a.left = &d;
b.right = &c;
b.left = &e;
cout << a << endl;
Check(&a);
cout << *Balance(&a) << endl;
cout << "----------------" << endl;
}
{
// 1
// / \
// 2 4
// / \
// 3 5
// /
// 6
Node a('1', 4);
Node b('2', 3);
Node c('3', 2);
Node d('4', 1);
Node e('5', 1);
Node f('6', 1);
a.left = &b;
a.right = &d;
b.left = &c;
b.right = &e;
c.left = &f;
cout << a << endl;
Check(&a);
cout << *Balance(&a) << endl;
cout << "----------------" << endl;
}
{
// 1
// / \
// 2 4
// / \
// 3 5
// \
// 6
Node a('1', 4);
Node b('2', 3);
Node c('3', 2);
Node d('4', 1);
Node e('5', 1);
Node f('6', 1);
a.left = &b;
a.right = &d;
b.left = &c;
b.right = &e;
c.right = &f;
cout << a << endl;
Check(&a);
cout << *Balance(&a) << endl;
cout << "----------------" << endl;
}
{
// 1
// / \
// 2 4
// / \
// 3 5
// /
// 6
Node a('1', 4);
Node b('2', 3);
Node c('3', 1);
Node d('4', 1);
Node e('5', 2);
Node f('6', 1);
a.left = &b;
a.right = &d;
b.left = &c;
b.right = &e;
e.left = &f;
cout << a << endl;
Check(&a);
cout << *Balance(&a) << endl;
cout << "----------------" << endl;
}
{
// 1
// / \
// 2 4
// / \
// 3 5
// \
// 6
Node a('1', 4);
Node b('2', 3);
Node c('3', 1);
Node d('4', 1);
Node e('5', 2);
Node f('6', 1);
a.left = &b;
a.right = &d;
b.left = &c;
b.right = &e;
e.right = &f;
cout << a << endl;
Check(&a);
cout << *Balance(&a) << endl;
cout << "----------------" << endl;
}
}
更新树高
/*
* 更新树高
*/
int UpdateHeight(Node* root){
if(NULL == root) return 0;
if(NULL == root->left && NULL == root->right) {
root->height = 1;
} else if(NULL == root->left) {
root->height = 1 + UpdateHeight(root->right);
} else if(NULL == root->right) {
root->height = 1 + UpdateHeight(root->left);
} else {
root->height = 1 + max(UpdateHeight(root->left),UpdateHeight(root->right));
}
return root->height;
}
插入
与 BST(二叉搜索树)中类似,先进行一次失败的查找来确定插入的位置,插入节点后根据平衡因子来决定是否需要调整。
/*
* 插入AVL树
*/
bool Insert(Node*& root,char key){
bool res;
if (NULL == root){
root = new Node(key);
res = true;
} else if (root->key == key){
res = false;
} else if (root->key < key){
res = Insert(root->right, key);
} else {
res = Insert(root->left, key);
}
if(res){
root = Balance(root);
UpdateHeight(root); // 更新高度
}
return res;
}
删除
删除和 BST 类似,将结点与后继交换后再删除。
删除会导致树高以及平衡因子变化,这时需要沿着被删除结点到根的路径来调整这种变化。
优点
查找、插入和删除在平均和最坏情况下都是O(logn)。
缺点
插入和删除旋转比较耗时,适用于插入和删除较少的情况。
参考代码
#include
#include
using namespace std;
struct Node{
int key; ///< 键
Node *left; ///< 左子节点
Node *right; ///< 右子节点
int height; ///< 节点高度
Node(int key, int height)
:key(key),left(NULL),right(NULL),height(height){}
};
// 辅助操作
Node* Maximum(Node* node){
if (NULL == node) return NULL;
while (NULL != node->right) node = node->right;
return node;
}
Node* Minimum(Node* node){
if (NULL == node) return NULL;
while (NULL != node->left) node = node->left;
return node;
}
// 平衡因子:左子树树高-右子树树高
int BalanceFactor(const Node* root){
if(NULL == root) return 0;
if(NULL == root->left && NULL == root->right) return 0;
if(NULL == root->left) return -root->right->height;
if(NULL == root->right) return root->left->height;
return root->left->height - root->right->height;
}
/*
* 右旋
* Q P
* / \ / \
* P C -------> A Q
* / \ / / \
* A B X' B C
*
*/
Node* RightRotate(Node* root){
Node* pivot = root->left; // 获取旋转节点
root->left = pivot->right; // 旋转节点的子节点替换父节点的旋转节点
pivot->right = root; // 旋转节点父节点做旋转节点子节点
return pivot; // 返回旋转节点
}
/*
* 左旋
* P Q
* / \ / \
* A Q -----> P C
* / \ / \ \
* B C A B X'
*/
Node* LeftRotate(Node* root){
Node* pivot = root->right; // 获取旋转节点
root->right = pivot->left; // 旋转节点的子节点替换父节点的旋转节点
pivot->left = root; // 旋转节点父节点做旋转节点子节点
return pivot; // 返回旋转节点
}
// 更新树高
int UpdateHeight(Node* root){
if(NULL == root) return 0;
if(NULL == root->left && NULL == root->right) {
root->height = 1;
} else if(NULL == root->left) {
root->height = 1 + UpdateHeight(root->right);
} else if(NULL == root->right) {
root->height = 1 + UpdateHeight(root->left);
} else {
root->height = 1 + max(UpdateHeight(root->left),UpdateHeight(root->right));
}
return root->height;
}
// 平衡
Node* Balance(Node* root){
Node *res = root;
int nf = BalanceFactor(root);
if(nf>1){
int lf = BalanceFactor(root->left);
if(lf > 0) { // LL
cout << "LL" << endl;
res = RightRotate(root);
} else { // LR
cout << "LR" << endl;
root->left = LeftRotate(root->left);
res = RightRotate(root);
}
}else if(nf <-1){
int rf = BalanceFactor(root->right);
if (rf < 0) { // RR
cout << "RR" << endl;
res = LeftRotate(root);
} else { // RL
cout << "RL" << endl;
root->right = RightRotate(root->right);
res = LeftRotate(root);
}
}else{
cout << "Balance" << endl;
// 保持平衡的情况
// return res;
}
UpdateHeight(res);
return res;
}
// 三个核心操作
Node* Insert(Node* node, int key){
if(NULL == node) node = new Node(key,1);
if (key < node->key) node->left = Insert(node->left, key);
else if (key > node->key) node->right = Insert(node->right,key);
node = Balance(node); // 平衡
return node;
}
Node* Search(Node* node, int key){
if(NULL == node) return NULL;
if (key < node->key) return Search(node->left, key);
else if (key > node->key) return Search(node->right, key);
return node;
}
Node* Remove(Node* node, int key){
if(NULL == node) return NULL;
if (key < node->key) node->left = Remove(node->left, key);
else if (key > node->key) node->right = Remove(node->right, key);
else {
if(NULL != node->right && NULL != node->left){// 有两个子树
// 最小值删除
Node* p = Minimum(node->right);
node->key = p->key;
node->right = Remove(node->right,p->key);
} else {// 叶子节点或者只有一个子树
Node* res = NULL;
if(NULL != node->right) res = node->right;
if(NULL != node->left) res = node->left;
delete node;
node = NULL;
return res;
}
}
node = Balance(node); // 平衡
return node;
}
/////////////////////////////////////////////////////////////
ostream& operator<<(ostream& os,const Node root) {
queue q;
q.push(&root);
while(!q.empty()){
const Node* curr = q.front();
q.pop();
if (NULL != curr){
os << curr->key << '[' << curr->height <<']';
q.push(curr->left);
q.push(curr->right);
} else {
os << '#';
}
}
return os;
}
void TestInsert(Node*& root){
root = Insert(root,1);
root = Insert(root,2);
root = Insert(root,3);
root = Insert(root,4);
root = Insert(root,5);
cout << *root << endl;
}
void TestSearch(Node* root,int key){
cout <<"Search " << key << ":" << Search(root,key) << endl;
}
void TestRemove(Node*& root,int key){
root = Remove(root, key);
cout <<"Remove " << key << ":" ;
if(NULL != root) cout << *root << endl;
else cout << "#" << endl;
}
void TestMax(Node* root){
Node* maxNode = Maximum(root);
cout << "Max:"<< maxNode->key <<":"<< maxNode <key <<":"<< minNode <