数据结构(十一)、C++ 平衡二叉树

(十一)、C++ 平衡二叉树

#include <iostream>
#include <queue>
/**
 * @namespace 平衡二叉树
 */
namespace tree_AVL
{
    template<class T>
    class Tree
    {
    public:
        struct node
        {
            node(T m_pData) :m_Tdata(m_pData), m_left(nullptr), m_right(nullptr) {}
            T m_Tdata;
            node* m_left;
            node* m_right;
        };
        Tree() :m_root(nullptr) {}

        /**
         * @brief 插入
         * @param m_pData: 插入值
         */
        void insert(T m_pData)
        {
            m_root = insert(m_root, m_pData);
        }

        /**
         * @brief 删除
         * @param m_pData: 删除值
         */
        void remove(T m_pData)
        {
            m_root = remove(m_root, m_pData);
        }

        /** 
         * @brief 返回树的高度
         */
        int height(node* m_pRoot)
        {
            if (m_pRoot == NULL)
                return 0;
            return 1 + std::max(height(m_pRoot->m_left), height(m_pRoot->m_right));
        }

        /** 
         * @brief 返回左右子树的高度差
         */
        int getBalance(node* m_pRoot) { return height(m_pRoot->m_left) - height(m_pRoot->m_right); }

        /** 
         * @brief 返回右旋转后的节点
         */
        node* rightRotate(node* m_pRoot)
        {
            node* t = m_pRoot->m_left;
            node* u = t->m_right;
            t->m_right = m_pRoot;
            m_pRoot->m_left = u;
            return t;
        }

        /**
         * @brief 返回左旋转后的节点 
         */
        node* leftRotate(node* m_pRoot)
        {
            node* t = m_pRoot->m_right;
            node* u = t->m_left;
            t->m_left = m_pRoot;
            m_pRoot->m_right = u;
            return t;
        }

        /**
         * @brief 返回树中具有最小值的节点
         */
        node* minValue(node* m_pRoot)
        {
            if (m_pRoot->m_left == NULL)
                return m_pRoot;
            return minValue(m_pRoot->m_left);
        }

        /**
         * @brief 层次遍历
         */
        void print_level()
        {
            std::queue<node*> queTree;
            node* temp = m_root;
            queTree.push(temp);
            while (!queTree.empty())
            {
                temp = queTree.front();
                std::cout << temp->m_Tdata << " ";
                queTree.pop();

                if (temp->m_left != nullptr)
                    queTree.push(temp->m_left);
                if (temp->m_right != nullptr)
                    queTree.push(temp->m_right);
            }
            std::cout << std::endl;
        }

    private:
        /**
         * @brief 插入
         * @param m_pRoot: 节点
         * @param m_pData: 插入值
         */
        node* insert(node* m_pRoot, T m_pData)
        {
            if (m_pRoot == NULL)
                return new node(m_pData);
            if (m_pData < m_pRoot->m_Tdata)
                m_pRoot->m_left = insert(m_pRoot->m_left, m_pData);
            else
                m_pRoot->m_right = insert(m_pRoot->m_right, m_pData);
            int b = getBalance(m_pRoot);                               // 平衡因子
            if (b > 1)                                                 // 左子树失衡
            {
                if (getBalance(m_pRoot->m_left) < 0)
                    m_pRoot->m_left = leftRotate(m_pRoot->m_left);     // Left-Right Case
                return rightRotate(m_pRoot);                           // Left-Left Case
            }
            else if (b < -1)                                           // 右子树失衡
            {
                if (getBalance(m_pRoot->m_right) > 0)
                    m_pRoot->m_right = rightRotate(m_pRoot->m_right);  // Right-Left Case
                return leftRotate(m_pRoot);                            // Right-Right Case
            }
            return m_pRoot;
        }

        /**
         * @brief 删除
         * @param m_pRoot: 节点
         * @param m_pData: 删除值
         */
        node* remove(node* m_pRoot, T m_pData)
        {
            if (m_pRoot == nullptr)
                return m_pRoot;
            if (m_pData < m_pRoot->m_Tdata)         // 删除节点位于左子树
                m_pRoot->m_left = remove(m_pRoot->m_left, m_pData);
            else if (m_pData > m_pRoot->m_Tdata)    // 删除节点位于右子树
                m_pRoot->m_right = remove(m_pRoot->m_right, m_pData);
            else                                    // 找到该节点所在
            {
                if (m_pRoot->m_right == nullptr)    // 要删除的节点是叶节点或只有一个子节点
                {
                    node* temp = m_pRoot->m_left;
                    delete (m_pRoot);
                    m_pRoot = nullptr;
                    return temp;
                }
                else if (m_pRoot->m_left == nullptr)
                {
                    node* temp = m_pRoot->m_right;
                    delete (m_pRoot);
                    m_pRoot = nullptr;
                    return temp;
                }
                // 要删除的节点同时具有左子树和右子树
                node* temp = minValue(m_pRoot->m_right);    // 找到右子树的最小节点
                m_pRoot->m_Tdata = temp->m_Tdata;           // 将最小节点的值赋值给找到的节点,然后去删除上一步找到的右子树的最小节点
                m_pRoot->m_right = remove(m_pRoot->m_right, temp->m_Tdata);
            }
            // Balancing Tree after deletion
            return m_pRoot;
        }

    private:
        node* m_root;
    };

void test_tree_AVL()
    {
        tree_AVL::Tree<int> m_tree;
        m_tree.insert(1);
        /*
                   (1)
        */

        m_tree.insert(4);
        /*
                   (1)
                     \
                     (4)
        */

        m_tree.insert(3);
        /*
                   (1)     平衡        (3)
                     \    =====>       / \
                     (4)            (1)   (4)
                    /
                  (3)
        */

        m_tree.insert(7);
        /*
                (3)                
                / \          
             (1)   (4)       
                     \
                     (7)             
        */

        m_tree.insert(8);
        /*                                       
                (3)                                  (3)
                / \                                  / \ 
             (1)   (4)             平衡           (1)   (7)     
                     \            =====>               /   \     
                     (7)                             (4)    (8)
                        \                                    
                        (8)                                  
        */

        m_tree.insert(2);
        /*
                   (3)                                    (3)
                   / \                                   /   \        
                (1)   (7)             平衡            (1)     (7)     
                     /   \           =====>             \    /   \    
                   (4)    (8)                          (2)  (4)    (8)
                           
        */

        std::cout << "AVL 层次遍历(队列实现):";
        m_tree.print_level();      // 3 1 7 2 4 8

        std::cout << "AVL 删除(3):";
        m_tree.remove(3);
        /*
                   (3)                                    (4)
                  /   \                                  /   \
               (1)     (7)           删除(3)          (1)     (7)
                 \    /   \          =====>             \        \
                (2) (4)   (8)                          (2)       (8)

        */

        m_tree.print_level();      // 4 1 7 2 8
    }
}// namespace tree_AVL

int main()
{
	tree_AVL::test_tree_AVL();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值