Blue is white,dark is not blue(AVL树)

#include <iostream>
#include <deque>
class AVLTree
{
private:
    struct Node
    {
        int data; //元素
        Node * left = nullptr; //左孩子
        Node * right = nullptr; //右孩子
        int height = -1; //节点高度
        Node(int data, int height) :data(data), height(height) {};
    };
    Node * root = nullptr; //根节点

    bool internalPush(Node * & root, int value)
    {
        bool result = false; //操作结果
        if (root == nullptr) //如果找到合适的位置 新建对象并且用当前指针指向它
        {
            root = new Node(value, 0);
            result = true;
        }
        else if (root->data == value) //如果已经有改元素 结果为失败 不做处理
        {
            result = false;
        }
        else if (root->data > value)
        {
            result = internalPush(root->left, value); //在左子树中寻找合适的位置
            if (nodeHeight(root->left) - nodeHeight(root->right) == 2) //判断当前节点是否失去平衡
            {
                if (root->left->data > value) //如果左子树的根节点的值大于插入值 表明是插入在左子树的左边
                {
                    singleRight(root); //单次右旋
                }
                else
                {
                    leftRight(root); //先左旋在右旋
                }
            }
        }
        else
        {
            result = internalPush(root->right, value);
            if (nodeHeight(root->right) - nodeHeight(root->left) == 2)
            {
                if (root->right->data < value)
                {
                    singleLeft(root);
                }
                else
                {
                    rightLeft(root);
                }
            }

        }
        root->height = treeHeight(root->left, root->right); //更新节点高度
        return result;
    }

    void singleRight(Node * & node)
    {
        Node * temp = node->left; //因为node的left要挂载left的right 所以需要先保存node的left 防止指针丢失
        node->left = temp->right; //node的left指向 temp的right
        temp->right = node;
        node->height = treeHeight(node->left, node->right); //先计算当前右子树的高度
        temp->height = treeHeight(temp->left, temp->right); //在计算子树的高度
        node = temp; //将当前子树绑定整个AVL树
    }

    void singleLeft(Node *& node)
    {
        Node * temp = node->right;
        node->right = temp->left;
        temp->left = node;
        node->height = treeHeight(node->left, node->right);
        temp->height = treeHeight(temp->left, temp->right);
        node = temp;
    }

    void leftRight(Node *& node)
    {
        singleLeft(node->left);
        singleRight(node);
    }

    void rightLeft(Node *& node)
    {
        singleRight(node->right);
        singleLeft(node);
    }

    int nodeHeight(Node * node)
    {
        return node == nullptr ? -1 : node->height;
    }

    int treeHeight(Node * left, Node * right)
    {
        return nodeHeight(left) > nodeHeight(right) ? nodeHeight(left) + 1 : nodeHeight(right) + 1;
    }

    bool internalRemove(Node *& root, int value)
    {
        bool result = false;
        if (root == nullptr) //删除失败
        {
            result = false;
        }
        else if (root->data > value)
        {
            result = internalRemove(root->left, value);
            if (nodeHeight(root->right) - nodeHeight(root->left) == 2)
            {
                // 通过树高比较 选择旋转类型
                if (nodeHeight(root->right->right) > nodeHeight(root->right->left))
                {
                    singleLeft(root);
                }
                else
                {
                    rightLeft(root);
                }
            }
        }
        else if (root->data < value)
        {
            result = internalRemove(root->right, value);
            if (nodeHeight(root->left) - nodeHeight(root->right) == 2)
            {
                if (nodeHeight(root->left->left) > nodeHeight(root->left->right))
                {
                    singleRight(root);
                }
                else
                {
                    leftRight(root);
                }
            }
        }
        else
        {
            if (root->left == nullptr && root->right == nullptr)
            {
                delete root;
                root = nullptr;
                result = true;
            }
            else if (root->left != nullptr && root->right == nullptr)
            {
                //将当前节点的左孩子赋值给自己 然后释放内存
                Node * temp = root;
                root = root->left;
                delete temp;
                result = true;
            }
            else if (root->right != nullptr && root->left == nullptr)
            {
                Node * temp = root;
                root = root->right;
                delete temp;
                result = true;
            }
            else
            {
                //将左子树最小的值赋给它 然后删除右子树最小值
                int miniValue = findMini(root->right);
                root->data = miniValue;
                result = internalRemove(root->right, miniValue);
                if (nodeHeight(root->left) - nodeHeight(root->right) == 2)
                {
                    if (nodeHeight(root->left->left) > nodeHeight(root->left ->right))
                    {
                        singleRight(root);
                    }
                    else
                    {
                        leftRight(root);
                    }
                }
            }


        }
        if (root != nullptr)
        {
            root->height = treeHeight(root->left, root->right);
        }

        return result;
    }

    int findMini(Node * node)
    {
        if (node == nullptr)
        {
            throw;
        }
        Node * pre = node;
        while (node != nullptr)
        {
            pre = node;
            node = node->left;
        }
        return pre->data;
    }

public:
    bool push(int value)
    {
        return internalPush(root, value);
    }

    bool remove(int value)
    {
        return internalRemove(root, value);
    }

    bool contains(int value)
    {
        Node * cursor = root;

        while(cursor != nullptr)
        {
            if(cursor->data == value)
            {
                return true;
            }
            else if(cursor->data > value)
            {
                cursor = cursor->left;
            }
            else
            {
                cursor = cursor->right;
            }
        }
        return false;
    }

    void floorTraversalPrint()
    {
        if (root != nullptr)
        {
            std::deque<Node *> q;
            q.push_back(root);

            while (!q.empty())
            {
                Node *  temp = q.front();
                std::cout << temp->data << std::ends;
                if (temp->left != nullptr)
                {
                    q.push_back(temp->left);
                }
                if (temp->right != nullptr)
                {
                    q.push_back(temp->right);
                }
                q.pop_front();
            }

        }
    }
};

int main(int args, char *argv[])
{
    AVLTree tree;
    tree.push(233);
    tree.push(32);
    tree.floorTraversalPrint();
    std::cout << tree.contains(3332) ;
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值