您的位置:首页 > 其它

Geeks - AVL Tree Deletion 平衡二叉树 删除操作

2014-05-27 10:41 337 查看
注意:

1 判断一个节点是否平衡的方法

2 平衡一个节点的方法 :

我这里比原文改进一点,独立出一个平衡节点的函数balanceNode(),这样一个函数可以用来平衡插入和删除操作,使得代码更加简洁了。

这样修改之后就使得平衡二叉树好像和一般二叉树的操作比较,就是多了一个平衡操作。

3 删除操作情况很多,很困难,一定要理清思路。十分容易出bug的地方。

这里是查找后继节点的值,填补上到需要删除的节点,然后删除后继节点,然后从后继节点往上判断,一个一个节点做平衡操作。

原文参考:http://www.geeksforgeeks.org/avl-tree-set-2-deletion/

#pragma once
#include <stdio.h>
#include <algorithm>

using std::max;

class AVL_Deletion
{
struct Node
{
int key;
Node *left, *right;
int h;
Node(int k) : key(k), left(NULL), right(NULL), h(1) {}
~Node()
{
if (left) delete left;
if (right) delete right;
}
};

void updateHeight(Node *n)
{
n->h = max(getHeight(n->left), getHeight(n->right)) + 1;
}

int getHeight(Node *n)
{
if (!n) return 0;
return n->h;
}

Node *leftRotate(Node *y)
{
Node *x = y->right;
y->right = x->left;
x->left = y;

updateHeight(y);
updateHeight(x);
return x;
}

Node *rightRotate(Node *y)
{
Node *x = y->left;
y->left = x->right;
x->right = y;

updateHeight(y);
updateHeight(x);
return x;
}

int getBalance(Node *n)
{
if (!n) return 0;
return getHeight(n->left) - getHeight(n->right);
}

Node *balanceNode(Node *n)
{
if (!n) return n;

updateHeight(n);

int balance = getBalance(n);

if (balance > 1 && getBalance(n->left) >= 0)
return rightRotate(n);
if (balance < -1 && getBalance(n->right) <= 0)
return leftRotate(n);
if (balance > 1 && getBalance(n->left) < 0)
{
n->left = leftRotate(n->left);
return rightRotate(n);
}
if (balance < -1 && getBalance(n->right) > 0)
{
n->right = rightRotate(n->right);
return leftRotate(n);
}
return n;
}

Node *insert(Node *n, int key)
{
if (!n) return new Node(key);

if (key < n->key) n->left = insert(n->left, key);
else n->right = insert(n->right, key);

return balanceNode(n);
}

Node *minValueNode(Node *n)
{
if (!n) return n;
Node *cur = n;
while (cur->left) cur = cur->left;
return cur;
}

Node *delNode(Node *r, int key)
{
if (!r) return r;

if (key < r->key) r->left = delNode(r->left, key);
else if (r->key < key) r->right = delNode(r->right, key);
else
{
if (!r->left || !r->right)
{
Node *t = r->left? r->left : r->right;
if (!t)
{
t = r;
r = NULL;
}
else *r = *t;//copy content, be careful about the *
free(t);
}
else
{
//key step: get inorder successor
Node *t = minValueNode(r->right);
r->key = t->key;
r->right = delNode(r->right, t->key);
}
}
return balanceNode(r);
}

void preOrder(Node *root)
{
if(root != NULL)
{
printf("%d ", root->key);
preOrder(root->left);
preOrder(root->right);
}
}
public:
AVL_Deletion()
{
Node *root = NULL;

/* Constructing tree given in the above figure */
root = insert(root, 9);
root = insert(root, 5);
root = insert(root, 10);
root = insert(root, 0);
root = insert(root, 6);
root = insert(root, 11);
root = insert(root, -1);
root = insert(root, 1);
root = insert(root, 2);

/* The constructed AVL Tree would be
9
/ \
1 10
/ \ \
0 5 11
/ / \
-1 2 6
*/

printf("Pre order traversal of the constructed AVL tree is \n");
preOrder(root);

root = delNode(root, 10);

/* The AVL Tree after deletion of 10
1
/ \
0 9
/ / \
-1 5 11
/ \
2 6
*/

printf("\nPre order traversal after deletion of 10 \n");
preOrder(root);
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: