avl tree

#ifndef _AVL_TREE_HPP_

#define _AVL_TREE_HPP_

 

#include <iomanip>

#include <iostream>

using namespace std;

 

template <class KeyType>

class AVLTreeNode

{

public:

    KeyType key;        // 关键字(键值)

    int height;         // 高度

    AVLTreeNode *left;  // 左孩子

    AVLTreeNode *right; // 右孩子

 

    AVLTreeNode(KeyType value, AVLTreeNode *l, AVLTreeNode *r) : key(value), height(0), left(l), right(r) {}

};

 

template <class KeyType>

class AVLTree

{

private:

    AVLTreeNode<KeyType> *mRoot; // 根结点

 

public:

    AVLTree();

    ~AVLTree();

 

    // 获取树的高度

    int height();

    // 获取树的高度

    int max(int a, int b);

 

    // 前序遍历"AVL树"

    void preOrder();

    // 中序遍历"AVL树"

    void inOrder();

    // 后序遍历"AVL树"

    void postOrder();

 

    // (递归实现)查找"AVL树"中键值为key的节点

    AVLTreeNode<KeyType> *search(KeyType key);

    // (非递归实现)查找"AVL树"中键值为key的节点

    AVLTreeNode<KeyType> *iterativeSearch(KeyType key);

 

    // 查找最小结点:返回最小结点的键值。

    KeyType minimum();

    // 查找最大结点:返回最大结点的键值。

    KeyType maximum();

 

    // 将结点(key为节点键值)插入到AVL树中

    void insert(KeyType key);

 

    // 删除结点(key为节点键值)

    void remove(KeyType key);

 

    // 销毁AVL树

    void destroy();

 

    // 打印AVL树

    void print();

 

private:

    // 获取树的高度

    int height(AVLTreeNode<KeyType> *tree);

 

    // 前序遍历"AVL树"

    void preOrder(AVLTreeNode<KeyType> *tree) const;

    // 中序遍历"AVL树"

    void inOrder(AVLTreeNode<KeyType> *tree) const;

    // 后序遍历"AVL树"

    void postOrder(AVLTreeNode<KeyType> *tree) const;

 

    // (递归实现)查找"AVL树x"中键值为key的节点

    AVLTreeNode<KeyType> *search(AVLTreeNode<KeyType> *x, KeyType key) const;

    // (非递归实现)查找"AVL树x"中键值为key的节点

    AVLTreeNode<KeyType> *iterativeSearch(AVLTreeNode<KeyType> *x, KeyType key) const;

 

    // 查找最小结点:返回tree为根结点的AVL树的最小结点。

    AVLTreeNode<KeyType> *minimum(AVLTreeNode<KeyType> *tree);

    // 查找最大结点:返回tree为根结点的AVL树的最大结点。

    AVLTreeNode<KeyType> *maximum(AVLTreeNode<KeyType> *tree);

 

    // LL:左左对应的情况(左单旋转)。

    AVLTreeNode<KeyType> *leftLeftRotation(AVLTreeNode<KeyType> *k2);

 

    // RR:右右对应的情况(右单旋转)。

    AVLTreeNode<KeyType> *rightRightRotation(AVLTreeNode<KeyType> *k1);

 

    // LR:左右对应的情况(左双旋转)。

    AVLTreeNode<KeyType> *leftRightRotation(AVLTreeNode<KeyType> *k3);

 

    // RL:右左对应的情况(右双旋转)。

    AVLTreeNode<KeyType> *rightLeftRotation(AVLTreeNode<KeyType> *k1);

 

    // 将结点(z)插入到AVL树(tree)中

    AVLTreeNode<KeyType> *insert(AVLTreeNode<KeyType> *&tree, KeyType key);

 

    // 删除AVL树(tree)中的结点(z),并返回被删除的结点

    AVLTreeNode<KeyType> *remove(AVLTreeNode<KeyType> *&tree, AVLTreeNode<KeyType> *z);

 

    // 销毁AVL树

    void destroy(AVLTreeNode<KeyType> *&tree);

 

    // 打印AVL树

    void print(AVLTreeNode<KeyType> *tree, KeyType key, int direction);

};

 

/*

 * 构造函数

 */

template <class KeyType>

AVLTree<KeyType>::AVLTree() : mRoot(NULL)

{

}

 

/*

 * 析构函数

 */

template <class KeyType>

AVLTree<KeyType>::~AVLTree()

{

    destroy(mRoot);

}

 

/*

 * 获取树的高度

 */

template <class KeyType>

int AVLTree<KeyType>::height(AVLTreeNode<KeyType> *tree)

{

    if (tree != NULL)

        return tree->height;

 

    return 0;

}

 

template <class KeyType>

int AVLTree<KeyType>::height()

{

    return height(mRoot);

}

/*

 * 比较两个值的大小

 */

template <class KeyType>

int AVLTree<KeyType>::max(int a, int b)

{

    return a > b ? a : b;

}

 

/*

 * 前序遍历"AVL树"

 */

template <class KeyType>

void AVLTree<KeyType>::preOrder(AVLTreeNode<KeyType> *tree) const

{

    if (tree != NULL)

    {

        cout << tree->key << " ";

        preOrder(tree->left);

        preOrder(tree->right);

    }

}

 

template <class KeyType>

void AVLTree<KeyType>::preOrder()

{

    preOrder(mRoot);

}

 

/*

 * 中序遍历"AVL树"

 */

template <class KeyType>

void AVLTree<KeyType>::inOrder(AVLTreeNode<KeyType> *tree) const

{

    if (tree != NULL)

    {

        inOrder(tree->left);

        cout << tree->key << " ";

        inOrder(tree->right);

    }

}

 

template <class KeyType>

void AVLTree<KeyType>::inOrder()

{

    inOrder(mRoot);

}

 

/*

 * 后序遍历"AVL树"

 */

template <class KeyType>

void AVLTree<KeyType>::postOrder(AVLTreeNode<KeyType> *tree) const

{

    if (tree != NULL)

    {

        postOrder(tree->left);

        postOrder(tree->right);

        cout << tree->key << " ";

    }

}

 

template <class KeyType>

void AVLTree<KeyType>::postOrder()

{

    postOrder(mRoot);

}

 

/*

 * (递归实现)查找"AVL树x"中键值为key的节点

 */

template <class KeyType>

AVLTreeNode<KeyType> *AVLTree<KeyType>::search(AVLTreeNode<KeyType> *x, KeyType key) const

{

    if (x == NULL || x->key == key)

        return x;

 

    if (key < x->key)

        return search(x->left, key);

    else

        return search(x->right, key);

}

 

template <class KeyType>

AVLTreeNode<KeyType> *AVLTree<KeyType>::search(KeyType key)

{

    return search(mRoot, key);

}

 

/*

 * (非递归实现)查找"AVL树x"中键值为key的节点

 */

template <class KeyType>

AVLTreeNode<KeyType> *AVLTree<KeyType>::iterativeSearch(AVLTreeNode<KeyType> *x, KeyType key) const

{

    while ((x != NULL) && (x->key != key))

    {

        if (key < x->key)

            x = x->left;

        else

            x = x->right;

    }

 

    return x;

}

 

template <class KeyType>

AVLTreeNode<KeyType> *AVLTree<KeyType>::iterativeSearch(KeyType key)

{

    return iterativeSearch(mRoot, key);

}

 

/*

 * 查找最小结点:返回tree为根结点的AVL树的最小结点。

 */

template <class KeyType>

AVLTreeNode<KeyType> *AVLTree<KeyType>::minimum(AVLTreeNode<KeyType> *tree)

{

    if (tree == NULL)

        return NULL;

 

    while (tree->left != NULL)

        tree = tree->left;

    return tree;

}

 

template <class KeyType>

KeyType AVLTree<KeyType>::minimum()

{

    AVLTreeNode<KeyType> *p = minimum(mRoot);

    if (p != NULL)

        return p->key;

 

    return (KeyType)NULL;

}

 

/*

 * 查找最大结点:返回tree为根结点的AVL树的最大结点。

 */

template <class KeyType>

AVLTreeNode<KeyType> *AVLTree<KeyType>::maximum(AVLTreeNode<KeyType> *tree)

{

    if (tree == NULL)

        return NULL;

 

    while (tree->right != NULL)

        tree = tree->right;

    return tree;

}

 

template <class KeyType>

KeyType AVLTree<KeyType>::maximum()

{

    AVLTreeNode<KeyType> *p = maximum(mRoot);

    if (p != NULL)

        return p->key;

 

    return (KeyType)NULL;

}

 

/*

 * LL:左左对应的情况(左单旋转)。

 *

 * 返回值:旋转后的根节点

 */

template <class KeyType>

AVLTreeNode<KeyType> *AVLTree<KeyType>::leftLeftRotation(AVLTreeNode<KeyType> *k2)

{

    AVLTreeNode<KeyType> *k1;

 

    k1 = k2->left;

    k2->left = k1->right;

    k1->right = k2;

 

    k2->height = max(height(k2->left), height(k2->right)) + 1;

    k1->height = max(height(k1->left), k2->height) + 1;

 

    return k1;

}

 

/*

 * RR:右右对应的情况(右单旋转)。

 *

 * 返回值:旋转后的根节点

 */

template <class KeyType>

AVLTreeNode<KeyType> *AVLTree<KeyType>::rightRightRotation(AVLTreeNode<KeyType> *k1)

{

    AVLTreeNode<KeyType> *k2;

 

    k2 = k1->right;

    k1->right = k2->left;

    k2->left = k1;

 

    k1->height = max(height(k1->left), height(k1->right)) + 1;

    k2->height = max(height(k2->right), k1->height) + 1;

 

    return k2;

}

 

/*

 * LR:左右对应的情况(左双旋转)。

 *

 * 返回值:旋转后的根节点

 */

template <class KeyType>

AVLTreeNode<KeyType> *AVLTree<KeyType>::leftRightRotation(AVLTreeNode<KeyType> *k3)

{

    k3->left = rightRightRotation(k3->left);

 

    return leftLeftRotation(k3);

}

 

/*

 * RL:右左对应的情况(右双旋转)。

 *

 * 返回值:旋转后的根节点

 */

template <class KeyType>

AVLTreeNode<KeyType> *AVLTree<KeyType>::rightLeftRotation(AVLTreeNode<KeyType> *k1)

{

    k1->right = leftLeftRotation(k1->right);

 

    return rightRightRotation(k1);

}

 

/*

 * 将结点插入到AVL树中,并返回根节点

 *

 * 参数说明:

 *     tree AVL树的根结点

 *     key 插入的结点的键值

 * 返回值:

 *     根节点

 */

template <class KeyType>

AVLTreeNode<KeyType> *AVLTree<KeyType>::insert(AVLTreeNode<KeyType> *&tree, KeyType key)

{

    if (tree == NULL)

    {

        // 新建节点

        tree = new AVLTreeNode<KeyType>(key, NULL, NULL);

        if (tree == NULL)

        {

            cout << "ERROR: create avltree node failed!" << endl;

            return NULL;

        }

    }

    else if (key < tree->key) // 应该将key插入到"tree的左子树"的情况

    {

        tree->left = insert(tree->left, key);

        // 插入节点后,若AVL树失去平衡,则进行相应的调节。

        if (height(tree->left) - height(tree->right) == 2)

        {

            if (key < tree->left->key)

                tree = leftLeftRotation(tree);

            else

                tree = leftRightRotation(tree);

        }

    }

    else if (key > tree->key) // 应该将key插入到"tree的右子树"的情况

    {

        tree->right = insert(tree->right, key);

        // 插入节点后,若AVL树失去平衡,则进行相应的调节。

        if (height(tree->right) - height(tree->left) == 2)

        {

            if (key > tree->right->key)

                tree = rightRightRotation(tree);

            else

                tree = rightLeftRotation(tree);

        }

    }

    else //key == tree->key)

    {

        cout << "添加失败:不允许添加相同的节点!" << endl;

    }

 

    tree->height = max(height(tree->left), height(tree->right)) + 1;

 

    return tree;

}

 

template <class KeyType>

void AVLTree<KeyType>::insert(KeyType key)

{

    insert(mRoot, key);

}

 

/*

 * 删除结点(z),返回根节点

 *

 * 参数说明:

 *     tree AVL树的根结点

 *     z 待删除的结点

 * 返回值:

 *     根节点

 */

template <class KeyType>

AVLTreeNode<KeyType> *AVLTree<KeyType>::remove(AVLTreeNode<KeyType> *&tree, AVLTreeNode<KeyType> *z)

{

    // 根为空 或者 没有要删除的节点,直接返回NULL。

    if (tree == NULL || z == NULL)

        return NULL;

 

    if (z->key < tree->key) // 待删除的节点在"tree的左子树"中

    {

        tree->left = remove(tree->left, z);

        // 删除节点后,若AVL树失去平衡,则进行相应的调节。

        if (height(tree->right) - height(tree->left) == 2)

        {

            AVLTreeNode<KeyType> *r = tree->right;

            if (height(r->left) > height(r->right))

                tree = rightLeftRotation(tree);

            else

                tree = rightRightRotation(tree);

        }

    }

    else if (z->key > tree->key) // 待删除的节点在"tree的右子树"中

    {

        tree->right = remove(tree->right, z);

        // 删除节点后,若AVL树失去平衡,则进行相应的调节。

        if (height(tree->left) - height(tree->right) == 2)

        {

            AVLTreeNode<KeyType> *l = tree->left;

            if (height(l->right) > height(l->left))

                tree = leftRightRotation(tree);

            else

                tree = leftLeftRotation(tree);

        }

    }

    else // tree是对应要删除的节点。

    {

        // tree的左右孩子都非空

        if ((tree->left != NULL) && (tree->right != NULL))

        {

            if (height(tree->left) > height(tree->right))

            {

                // 如果tree的左子树比右子树高;

                // 则(01)找出tree的左子树中的最大节点

                //   (02)将该最大节点的值赋值给tree。

                //   (03)删除该最大节点。

                // 这类似于用"tree的左子树中最大节点"做"tree"的替身;

                // 采用这种方式的好处是:删除"tree的左子树中最大节点"之后,AVL树仍然是平衡的。

                AVLTreeNode<KeyType> *max = maximum(tree->left);

                tree->key = max->key;

                tree->left = remove(tree->left, max);

            }

            else

            {

                // 如果tree的左子树不比右子树高(即它们相等,或右子树比左子树高1)

                // 则(01)找出tree的右子树中的最小节点

                //   (02)将该最小节点的值赋值给tree。

                //   (03)删除该最小节点。

                // 这类似于用"tree的右子树中最小节点"做"tree"的替身;

                // 采用这种方式的好处是:删除"tree的右子树中最小节点"之后,AVL树仍然是平衡的。

                AVLTreeNode<KeyType> *min = maximum(tree->right);

                tree->key = min->key;

                tree->right = remove(tree->right, min);

            }

        }

        else

        {

            AVLTreeNode<KeyType> *tmp = tree;

            tree = (tree->left != NULL) ? tree->left : tree->right;

            delete tmp;

        }

    }

 

    return tree;

}

 

template <class KeyType>

void AVLTree<KeyType>::remove(KeyType key)

{

    AVLTreeNode<KeyType> *z;

 

    if ((z = search(mRoot, key)) != NULL)

        mRoot = remove(mRoot, z);

}

 

/*

 * 销毁AVL树

 */

template <class KeyType>

void AVLTree<KeyType>::destroy(AVLTreeNode<KeyType> *&tree)

{

    if (tree == NULL)

        return;

 

    if (tree->left != NULL)

        destroy(tree->left);

    if (tree->right != NULL)

        destroy(tree->right);

 

    delete tree;

}

 

template <class KeyType>

void AVLTree<KeyType>::destroy()

{

    destroy(mRoot);

}

 

/*

 * 打印"二叉查找树"

 *

 * key        -- 节点的键值

 * direction  --  0,表示该节点是根节点;

 *               -1,表示该节点是它的父结点的左孩子;

 *                1,表示该节点是它的父结点的右孩子。

 */

template <class KeyType>

void AVLTree<KeyType>::print(AVLTreeNode<KeyType> *tree, KeyType key, int direction)

{

    if (tree != NULL)

    {

        if (direction == 0) // tree是根节点

            cout << setw(2) << tree->key << " is root" << endl;

        else // tree是分支节点

            cout << setw(2) << tree->key << " is " << setw(2) << key << "'s " << setw(12) << (direction == 1 ? "right child" : "left child") << endl;

 

        print(tree->left, tree->key, -1);

        print(tree->right, tree->key, 1);

    }

}

 

template <class KeyType>

void AVLTree<KeyType>::print()

{

    if (mRoot != NULL)

        print(mRoot, mRoot->key, 0);

}

#endif

 

 

 

 

/**

 * C++ 语言: AVL树

 *

 * @author dqsjqian

 * @date 2019/12/11

 */

 

#include <iostream>

#include "AVLTree.hpp"

using namespace std;

 

static int arr[] = {3, 2, 1, 4, 5, 6, 7, 16, 15, 14, 13, 12, 11, 10, 8, 9};

#define TBL_SIZE(a) ((sizeof(a)) / (sizeof(a[0])))

 

int main()

{

    int i, ilen;

    AVLTree<int> *tree = new AVLTree<int>();

 

    cout << "== 依次添加: ";

    ilen = TBL_SIZE(arr);

    for (i = 0; i < ilen; i++)

    {

        cout << arr[i] << " ";

        tree->insert(arr[i]);

    }

 

    cout << "\n== 前序遍历: ";

    tree->preOrder();

 

    cout << "\n== 中序遍历: ";

    tree->inOrder();

 

    cout << "\n== 后序遍历: ";

    tree->postOrder();

    cout << endl;

 

    cout << "== 高度: " << tree->height() << endl;

    cout << "== 最小值: " << tree->minimum() << endl;

    cout << "== 最大值: " << tree->maximum() << endl;

    cout << "== 树的详细信息: " << endl;

    tree->print();

 

    i = 8;

    cout << "\n== 删除根节点: " << i;

    tree->remove(i);

 

    cout << "\n== 高度: " << tree->height();

    cout << "\n== 中序遍历: ";

    tree->inOrder();

    cout << "\n== 树的详细信息: " << endl;

    tree->print();

 

    // 销毁二叉树

    tree->destroy();

 

    system("pause");

    return 0;

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dqsjqian

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值