最近在看c++,同时又在学习算法,所以这里我就用c++来写一些数据结构和算法。由于之前一直对avl耿耿于怀,所以我决定先把这个数据结构搞定,看来数据结构与算法分析上的描述(完全没有代码实现),我之前看了红黑的实现,所以觉得自己还是有信心完成的,于是拿起键盘自己独立实现了一发,事实证明,如果坚持不懈,那么自己能力范围之内的事情,我们一定可以做到!相比较于红黑树,avl树的实现在思路上是简单不少的,比较容易理解。插入时,从根节点向上找最早的不平衡节点,删除的时候从根节点向下找不平衡的节点,这是我实现的思路,不知道大神的实现是否和我一致那。不多说,记录一下我的代码吧。
#include
#include
using namespace std;
typedef int ELeType;
#define BALANCE 1
#define LEFT_SUBTREE 2
#define RIGHT_SUBTREE 3
class Avl_node {
friend class Avl_tree;
friend void travel_by_node (Avl_node *);
public:
Avl_node (ELeType n) : parent(nullptr) , left(nullptr) , right(nullptr) , key(n) {}
ELeType get_key () {
return key;
}
Avl_node *get_parent () {
return parent;
}
Avl_node *get_left () {
return left;
}
Avl_node *get_right () {
return right;
}
private:
void free ();
Avl_node *parent;
Avl_node *left;
Avl_node *right;
ELeType key;
};
class Avl_tree {
public:
Avl_tree (Avl_node *a) : root(a) {
root->parent = nullptr;
root->left = nullptr;
root->right = nullptr;
}
Avl_node *get_root () {
return root;
}
void delete_node (Avl_node *);
void insret_node (Avl_node *);
void travel_tree ();
int is_balance (Avl_node *);
int height_of_tree (Avl_node *);
private:
void do_to_balance_leaf (Avl_node *);
void do_to_balance_root ();
void right_rotate (Avl_node *);
void left_rotate (Avl_node *);
Avl_node *root;
};
void Avl_tree::insret_node (Avl_node *a) {
Avl_node *temp = root;
Avl_node *pre = nullptr;
enum {LEFT = 1};
enum {RIGHT = 2};
int flag;
while (temp != nullptr) {
pre = temp;
if (a->key > temp->key) {
temp = temp->right;
flag = RIGHT;
}
else {
temp = temp->left;
flag = LEFT;
}
}
if (flag == LEFT)
pre->left = a;
else
pre->right = a;
a->parent = pre;
do_to_balance_leaf (a);
}
void Avl_tree::delete_node (Avl_node *node) {
if (node == nullptr)
return;
else {
Avl_node *temp = nullptr;
if (node->left != nullptr) {
cout << "ok1" << endl;
node->left->parent = node->parent;
temp = node->left;
}else if (node->right != nullptr) {
cout << "ok2" << endl;
node->right->parent = node->parent;
temp = node->right;
}
if (node == root) {
root = temp;
}else {
if (node == node->parent->left)
node->parent->left = temp;
else
node->parent->right = temp;
}
node->free ();
}
do_to_balance_root ();
}
void Avl_tree::do_to_balance_leaf (Avl_node *node) {
Avl_node *temp_node = node;
Avl_node *pre_node;
int temp_type;
while ((temp_node != root) && (is_balance (temp_node) == BALANCE)) {
pre_node = temp_node;
temp_node = temp_node->parent;
}
if (temp_node == root && (is_balance (temp_node) == BALANCE))
return;
else {
if ((pre_node == pre_node->parent->left) &&
(height_of_tree (pre_node->left) > height_of_tree (pre_node->right)))
right_rotate (pre_node->parent);
else if ((pre_node == pre_node->parent->right) &&
(height_of_tree (pre_node->right) > height_of_tree (pre_node->left)))
left_rotate (pre_node->parent);
else if ((pre_node == pre_node->parent->left) &&
(height_of_tree (pre_node->left) < height_of_tree (pre_node->right))) {
left_rotate (pre_node);
right_rotate (pre_node->parent->parent);
}else if ((pre_node == pre_node->parent->right) &&
(height_of_tree (pre_node->right) < height_of_tree (pre_node->left))) {
right_rotate (pre_node);
left_rotate (pre_node->parent->parent);
}
}
}
void Avl_tree::do_to_balance_root () {
Avl_node *temp_node = root;
Avl_node *pre_node;
int temp_type;
if (temp_node == nullptr)
return;
while (((temp_type = is_balance (temp_node)) != BALANCE) && (temp_node != nullptr)) {
if (temp_type == RIGHT_SUBTREE)
temp_node = temp_node->right;
else
temp_node = temp_node->left;
}
if (temp_node == root)
return;
else {
if ((temp_node == temp_node->parent->left) &&
(height_of_tree (temp_node->left) > height_of_tree (temp_node->right)))
right_rotate (temp_node->parent);
else if ((temp_node == temp_node->parent->right) &&
(height_of_tree (temp_node->right) > height_of_tree (temp_node->left)))
left_rotate (temp_node->parent);
else if ((temp_node == temp_node->parent->left) &&
(height_of_tree (temp_node->left) < height_of_tree (temp_node->right))) {
left_rotate (temp_node);
right_rotate (temp_node->parent->parent);
}else if ((temp_node == temp_node->parent->right) &&
(height_of_tree (temp_node->right) < height_of_tree (temp_node->left))) {
right_rotate (temp_node);
left_rotate (temp_node->parent->parent);
}
}
}
void Avl_node::free () {
this->~Avl_node ();
}
void Avl_tree::left_rotate (Avl_node *a) {
Avl_node *b = a->right;
if (a->right == nullptr) {
cerr << "missing right child of arg in the function left_rotate" << endl;
return;
}else {
if (a->parent == nullptr) {
b->parent = nullptr;
root = b;
}else {
b->parent = a->parent;
if (a == a->parent->left)
a->parent->left = b;
else
a->parent->right = b;
}
a->right = b->left;
if (b->left != nullptr)
b->left->parent = a;
b->left = a;
a->parent = b;
}
}
void Avl_tree::right_rotate (Avl_node *a) {
Avl_node *b = a->left;
if (a->left == nullptr) {
cerr << "missing right child of arg in the function left_rotate" << endl;
return;
}else {
if (a->parent == nullptr) {
b->parent = a->parent;
root = b;
}else {
b->parent = a->parent;
if (a == a->parent->left)
a->parent->left = b;
else
a->parent->right = b;
}
a->left = b->right;
if (b->right != nullptr)
b->right->parent = a;
b->right = a;
a->parent = b;
}
}
int Avl_tree::height_of_tree (Avl_node *node) {
int res;
int height_left;
int height_right;
if (node == nullptr)
return 0;
else if (node->left == nullptr && node->right == nullptr)
return 1;
else {
height_left = 1 + height_of_tree (node->left);
height_right = 1 + height_of_tree (node->right);
res = (height_left > height_right) ? height_left : height_right;
return res;
}
}
int Avl_tree::is_balance (Avl_node *node) {
if (node == nullptr) {
return BALANCE;
}else {
int height_left = height_of_tree (node->left);
int height_right = height_of_tree (node->right);
if (abs (height_left - height_right) < 2)
return BALANCE;
else {
if (height_left > height_right)
return LEFT_SUBTREE;
else
return RIGHT_SUBTREE;
}
}
}
void travel_by_node (Avl_node *node) {
if (node != nullptr) {
cout << node->get_key () << " ";
travel_by_node (node->left);
travel_by_node (node->right);
}
}
void Avl_tree::travel_tree () {
travel_by_node (root);
}
int main () {
Avl_node a(1);
Avl_tree tree(&a);
for (int i = 2 ; i < 130 ; i++) {
Avl_node *temp = new Avl_node (i);
tree.insret_node (temp);
}
tree.delete_node (tree.get_root ());
if (tree.get_root () == nullptr)
cout << "error" << endl;
//tree.right_rotate (&c);
cout << "the height of tree is :" << tree.height_of_tree (tree.get_root ()) << endl;
if (tree.is_balance (tree.get_root ()) == BALANCE)
cout << "tree is balance" << endl;
else
cout << "tree is not balance" << endl;
tree.travel_tree ();
cout << endl;
}