avl树的c++实现

    最近在看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;
}

   

你可能感兴趣的:(算法导论)