数据结构之平衡二叉树(c++)

以下为平衡二叉树实现的操作。如果各位读者对平衡二叉树调整不理解的话,可以进入我的主页查看我关于介绍平衡二叉树调整的文章。

目录

  1. 插入结点
  2. 平衡二叉树合并
  3. 删除结点
  4. 前序遍历
  5. 中序遍历
  6. 后续遍历
  7. 层次遍历
  8. 更新结点值
  9. 查找指定结点
  10. 清空结点
  11. 获取结点总数
  12. 获取叶子结点个数
  13. 获取非叶子结点个数
  14. 树的高度
  15. 树的深度
  16. 树是否为空

下面请看代码:

#ifndef _AVLTree_H_
#define _AVLTree_H_

#include <utility>
#include <cmath>
#include <iostream>
#include <deque>
#include <vector>

#define MAX(a, b) (((a) > (b)) ? a : b)

template <class K, class V>
class AVLTree
{
public:
    class TreeNode
    {
    public:
        // 创建结点
        static TreeNode *createNode(const K &Key, const V &Value, const TreeNode *Parent = nullptr, const TreeNode *Lchild = nullptr, const TreeNode *Rchild = nullptr);

    private:
        // 左右孩子标识,true为左孩子,false为右孩子
        bool childFlag;
        // 子树高度
        int height;
        // 键值
        K key;
        // 值
        V value;
        // 父节点
        TreeNode *parent;
        // 左孩子节点
        TreeNode *Lchild;
        // 右孩子节点
        TreeNode *Rchild;

    private:
        TreeNode(const K &Key, const V &Value, const TreeNode *Parent = nullptr, const TreeNode *Lchild = nullptr, const TreeNode *Rchild = nullptr);

    public:
        // 获取孩子标识
        const bool getChildFlag() const;
        // 获取高度
        const int getHeight() const;
        // 获取键值
        const K getKey() const;
        // 获取值
        const V getValue() const;
        // 获取父节点
        const TreeNode *getParent() const;
        // 获取左孩子结点
        const TreeNode *getLchild() const;
        // 获取右孩子结点
        const TreeNode *getRchild() const;
        // 设置父节点
        void setParent(const TreeNode *Parent);
        // 设置左孩子结点
        void setLchild(const TreeNode *Lchild);
        // 设置右孩子结点
        void setRchild(const TreeNode *Rchild);
        // 设置键值
        void setKey(const K &Key);
        // 设置值
        void setValue(const V &Value);
        // 设置高度
        void setHeight(const int &Height);
        // 设置孩子标识
        void setChildFlag(const bool &NewFlag);
        // 节点是否平衡
        int isBalance() const;
        // 结点高度更新
        void updateHeight();
        // 添加子树
        void insertTree(TreeNode *Root, TreeNode *SubTree, bool Direction, bool *Stop);

    public:
        bool operator==(const TreeNode &Other) const;
    };

private:
    // 根节点
    TreeNode *root;
    // 结点数量
    int nodeSize;

public:
    AVLTree();

private:
    // 查找结点
    TreeNode *query(const TreeNode *Node, const K &Key) const;
    // 更新结点高度以及调整树平衡
    void update(TreeNode *Root);
    // 递归插入
    void recursionInsert(TreeNode *Before, TreeNode *NewNode);
    // 头结点插入
    void rootInsert(TreeNode *NewNode);
    // 前序遍历
    void preorderTraversal(const TreeNode *Node) const;
    // 中序遍历
    void middleTraversal(const TreeNode *Node) const;
    // 后续遍历
    void afterorderTraversal(const TreeNode *Node) const;
    // LL型
    void adjust_LL(TreeNode *Vandal);
    // RR型
    void adjust_RR(TreeNode *Vandal);
    // LR型
    void adjust_LR(TreeNode *Vandal);
    // Rl型
    void adjust_RL(TreeNode *Vandal);
    // 打印结点
    void PrintKey(const TreeNode *Node) const;
    // 插入子树
    void insertSubTree(const TreeNode *SubTree);
    // 清空
    void clear(TreeNode *Root);
    // 统计叶子结点个数
    void statisticsLeafNode(const TreeNode *Root, int *Size) const;

public:
    // 插入结点
    void insert(const K &key, const V &value);
    void insert(const TreeNode *Node);
    void insert(const std::vector<std::pair<K, V>> &vNode);
    void insert(const AVLTree *SubTree);
    // 删除结点
    void remove(const K &key);
    // 前序遍历
    void preorderTraversal() const;
    // 中序遍历
    void middleTraversal() const;
    // 后续遍历
    void afterorderTraversal() const;
    // 层次遍历
    void hierarchyTraversal() const;
    // 更新结点值
    void updateValue(const V &FindKey, const V &NewValue);
    // 查找指定结点
    const TreeNode *queryNode(const K &Key) const;
    // 清空结点
    void clear();
    // 获取结点总数
    int size() const;
    // 获取叶子结点个数
    int leafNodeSize() const;
    // 获取非叶子结点个数
    int notLeafNodeSize() const;
    // 树的高度
    int height() const;
    // 树的深度
    int depth() const;
    // 树是否为空
    bool isEmpty() const;
};

template <typename K, typename V>
AVLTree<K, V>::TreeNode::
    TreeNode(const K &Key, const V &Value, const TreeNode *Parent, const TreeNode *Lchild, const TreeNode *Rchild)
    : key(Key), value(Value), parent(const_cast<TreeNode *>(Parent)), Lchild(const_cast<TreeNode *>(Lchild)), Rchild(const_cast<TreeNode *>(Rchild)), height(0)
{
}
// 获取结点标识
template <class K, class V>
const bool AVLTree<K, V>::TreeNode::getChildFlag() const
{
    return this->childFlag;
}
// 获取结点高度
template <class K, class V>
const int AVLTree<K, V>::TreeNode::getHeight() const
{
    return this->height;
}

// 获取键值
template <typename K, typename V>
const K AVLTree<K, V>::TreeNode::getKey() const
{
    return this->key;
}
// 获取值
template <typename K, typename V>
const V AVLTree<K, V>::TreeNode::getValue() const
{
    return this->value;
}
// 获取父节点
template <typename K, typename V>
const typename AVLTree<K, V>::TreeNode *AVLTree<K, V>::TreeNode::getParent() const
{
    return this->parent;
}
// 获取左孩子结点
template <typename K, typename V>
const typename AVLTree<K, V>::TreeNode *AVLTree<K, V>::TreeNode::getLchild() const
{
    return this->Lchild;
}
// 获取右孩子结点
template <typename K, typename V>
const typename AVLTree<K, V>::TreeNode *AVLTree<K, V>::TreeNode::getRchild() const
{
    return this->Rchild;
}
// 设置父节点
template <typename K, typename V>
void AVLTree<K, V>::TreeNode::setParent(const TreeNode *Parent)
{
    this->parent = const_cast<TreeNode *>(Parent);
}
// 设置左孩子结点
template <typename K, typename V>
void AVLTree<K, V>::TreeNode::setLchild(const TreeNode *Lchild)
{
    this->Lchild = const_cast<TreeNode *>(Lchild);
}
// 设置右孩子结点
template <typename K, typename V>
void AVLTree<K, V>::TreeNode::setRchild(const TreeNode *Rchild)
{
    this->Rchild = const_cast<TreeNode *>(Rchild);
}
// 设置键值
template <typename K, typename V>
void AVLTree<K, V>::TreeNode::setKey(const K &Key)
{
    this->key = Key;
}
// 设置值
template <typename K, typename V>
void AVLTree<K, V>::TreeNode::setValue(const V &Value)
{
    this->value = Value;
}
// 设置结点高度
template <class K, class V>
void AVLTree<K, V>::TreeNode::setHeight(const int &Height)
{
    this->height = Height;
}
// 设置结点标识
template <class K, class V>
void AVLTree<K, V>::TreeNode::setChildFlag(const bool &NewFlag)
{
    this->childFlag = NewFlag;
}

// 节点是否平衡
template <typename K, typename V>
int AVLTree<K, V>::TreeNode::isBalance() const
{
    // 获取左右孩子
    auto Lchild = this->getLchild();
    auto Rchild = this->getRchild();
    int Lh = 0, Rh = 0;
    // 如果左孩子不为空,获取左子树高度
    if (Lchild)
        Lh = Lchild->getHeight() + 1;
    // 如果右孩子不为空,获取右子树高度
    if (Rchild)
        Rh = Rchild->getHeight() + 1;
    // 返回高度差
    return Lh - Rh;
}
// 结点高度更新
template <class K, class V>
void AVLTree<K, V>::TreeNode::updateHeight()
{
    Lchild = const_cast<TreeNode *>(this->getLchild());
    Rchild = const_cast<TreeNode *>(this->getRchild());
    // 左右子树为空,高度为零
    if (!Lchild && !Rchild)
        this->setHeight(0);
    // 右子树为空,高度为左子树高度加一
    else if (Lchild && !Rchild)
        this->setHeight(Lchild->getHeight() + 1);
    // 左子树为空,高度为右子树高度加一
    else if (!Lchild && Rchild)
        this->setHeight(Rchild->getHeight() + 1);
    // 左右子树都不为空
    else
    {
        // 高度左右子树的最大高度
        if (Lchild->getHeight() > Rchild->getHeight())
            this->setHeight(Lchild->getHeight() + 1);
        else
            this->setHeight(Rchild->getHeight() + 1);
    }
}
// 查找结点
template <class K, class V>
typename AVLTree<K, V>::TreeNode *AVLTree<K, V>::query(const TreeNode *Node, const K &Key) const
{
    // 结点为空,返回空指针
    if (Node == nullptr)
        return nullptr;
    // 与键值匹配,返回当前结点
    if (Node->getKey() == Key)
        return const_cast<TreeNode *>(Node);
    // 递归继续查找
    auto Lresult = query(Node->getLchild(), Key);
    if (Lresult)
        return Lresult;
    auto Rresult = query(Node->getRchild(), Key);
    if (Rresult)
        return Rresult;
    // 无匹配结点,返回空指针
    return nullptr;
}

template <class K, class V>
void AVLTree<K, V>::TreeNode::insertTree(TreeNode *Root, TreeNode *SubTree, bool Direction, bool *Stop)
{
    if (SubTree == nullptr || Root == nullptr || *Stop == true)
        return;

    if (Direction)
    {
        insertTree(const_cast<TreeNode *>(Root->getLchild()), SubTree, Direction, Stop);
        if (*Stop == false)
        {
            // 左子树插入
            Root->setLchild(SubTree);
            // 更新子树父节点
            SubTree->setParent(Root);
            // 终止递归更新结点
            *Stop = true;
        }
    }
    else
    {
        insertTree(const_cast<TreeNode *>(Root->getRchild()), SubTree, Direction, Stop);
        if (*Stop == false)
        {
            // 左子树插入
            Root->setRchild(SubTree);
            // 更新子树父节点
            SubTree->setParent(Root);
            // 终止递归更新结点
            *Stop = true;
        }
    }
}

template <class K, class V>
inline bool AVLTree<K, V>::TreeNode::operator==(const TreeNode &Other) const
{
    if (this->getKey() == Other.getKey())
        return true;
    return false;
}

// 创建结点
template <typename K, typename V>
typename AVLTree<K, V>::TreeNode *AVLTree<K, V>::TreeNode::createNode(const K &Key, const V &Value, const TreeNode *Parent, const TreeNode *Lchild, const TreeNode *Rchild)
{
    TreeNode *newNode = nullptr;
    newNode = new (std::nothrow) TreeNode(Key, Value, Parent, Lchild, Rchild);
    return newNode;
}

template <typename K, typename V>
AVLTree<K, V>::AVLTree() : root(nullptr), nodeSize(0)
{
}

// 更新结点高度以及调整树平衡
template <class K, class V>
void AVLTree<K, V>::update(TreeNode *Root)
{
    // 如果根结点为空,直接返回
    if (!Root)
        return;

    // 自底向上方法更新
    update(const_cast<TreeNode *>(Root->getLchild()));
    update(const_cast<TreeNode *>(Root->getRchild()));
    // 更新高度
    Root->updateHeight();
    // 如果平衡因子大于1,则为LL型或LR型
    if (1 < Root->isBalance())
    {
        // 如果被破坏者的左孩子的平衡因子等于1,则为LL型
        if (Root->getLchild()->isBalance() == 1)
        {

            this->adjust_LL(Root);
        }
        // 否则为LR型
        else
        {

            this->adjust_LR(Root);
        }
    }
    // 平衡因子小于-1,则为RR型或RL型
    else if (-1 > Root->isBalance())
    {
        // 如果被破坏者的右孩子的平衡因子等于-1,则为RR型
        if (Root->getRchild()->isBalance() == -1)
        {

            this->adjust_RR(Root);
        }
        // 否则为RL型
        else
        {
            this->adjust_RL(Root);
        }
    }
}

// 递归插入
template <class K, class V>
void AVLTree<K, V>::recursionInsert(TreeNode *Before, TreeNode *NewNode)
{
    if (Before == nullptr || NewNode == nullptr)
        return;
    // 获取当前左右孩子
    auto Lchild = Before->getLchild();
    auto Rchild = Before->getRchild();
    // 如果插入结点的键值大于当前结点
    if (NewNode->getKey() > Before->getKey())
    {
        // 当前结点右孩子为空,则直接插入
        if (Rchild == nullptr)
        {
            Before->setRchild(NewNode);
            // 更新插入结点的父节点
            NewNode->setParent(Before);
            // 更新结点标识
            NewNode->setChildFlag(false);
            // 更新结点数量
            this->nodeSize++;
        }

        // 否则继续递归
        else
        {
            recursionInsert(const_cast<TreeNode *>(Rchild), NewNode);
        }
    }
    // 如果插入结点的键值小于当前结点
    else if (NewNode->getKey() < Before->getKey())
    {
        // 如果左孩子为空,直接插入,否则继续递归
        if (Lchild == nullptr)
        {
            Before->setLchild(NewNode);
            // 更新插入结点的父节点
            NewNode->setParent(Before);
            // 更新结点标识
            NewNode->setChildFlag(true);
            // 更新结点数量
            this->nodeSize++;
        }
        else
        {
            recursionInsert(const_cast<TreeNode *>(Lchild), NewNode);
        }
    }
    // 既不大于也不小于,说明键值相等,则拒绝插入
    else
        return;
}

template <class K, class V>
void AVLTree<K, V>::rootInsert(TreeNode *NewNode)
{
    this->root = NewNode;
    // 更新结点数量
    this->nodeSize++;
}
// 前序遍历
template <class K, class V>
void AVLTree<K, V>::preorderTraversal(const TreeNode *Node) const
{
    // 如果结点为空,就返回
    if (!Node)
        return;
    this->PrintKey(Node);
    this->preorderTraversal(Node->getLchild());
    this->preorderTraversal(Node->getRchild());
}
// 中序遍历
template <class K, class V>
void AVLTree<K, V>::middleTraversal(const TreeNode *Node) const
{
    // 如果结点为空,就返回
    if (!Node)
        return;
    this->middleTraversal(Node->getLchild());
    this->PrintKey(Node);
    this->middleTraversal(Node->getRchild());
}
// 后序遍历
template <class K, class V>
void AVLTree<K, V>::afterorderTraversal(const TreeNode *Node) const
{
    // 如果结点为空,就返回
    if (!Node)
        return;
    this->afterorderTraversal(Node->getLchild());
    this->afterorderTraversal(Node->getRchild());
    this->PrintKey(Node);
}
// LL型 右旋
template <class K, class V>
void AVLTree<K, V>::adjust_LL(TreeNode *Vandal)
{
    TreeNode *adjustNode = const_cast<TreeNode *>(Vandal->getLchild());
    TreeNode *adjustRchild = const_cast<TreeNode *>(adjustNode->getRchild());
    // 将旋转结点的右孩子设置成被破坏者的左孩子
    Vandal->setLchild(adjustNode->getRchild());
    // 如果旋转结点有右孩子
    if (adjustRchild)
    {
        // 更新其父节点
        adjustRchild->setParent(Vandal);
        // 更新结点标识
        adjustRchild->setChildFlag(true);
    }
    // 如果被破坏者有父节点
    TreeNode *VandalParent = const_cast<TreeNode *>(Vandal->getParent());
    if (VandalParent)
    {
        // 根据被破坏者的结点标识来判断它是其父节点的左孩子还是右孩子
        if (Vandal->getChildFlag())
            // 将旋转结点作为被破坏者的左孩子
            VandalParent->setLchild(adjustNode);

        else
            // 将旋转结点作为被破坏者的右孩子
            VandalParent->setRchild(adjustNode);
    }
    // 将被破坏者作为旋转结点的右孩子
    adjustNode->setRchild(Vandal);
    // 更新旋转结点的父节点
    adjustNode->setParent(Vandal->getParent());
    // 更新旋转结点的标识
    adjustNode->setChildFlag(Vandal->getChildFlag());
    // 更新被破坏者的结点标记
    Vandal->setChildFlag(false);
    // 更新被破坏者的父节点
    Vandal->setParent(adjustNode);
    // 更新被破坏者结点高度
    Vandal->updateHeight();
    // 更新旋转结点的高度
    adjustNode->updateHeight();
    // 如果父节点为空,说明右旋之后,adjustNode变成了根节点
    if (adjustNode->getParent() == nullptr)
        // 更新根节点
        this->root = adjustNode;
}
// RR型 左旋
template <class K, class V>
void AVLTree<K, V>::adjust_RR(TreeNode *Vandal)
{
    TreeNode *adjustNode = const_cast<TreeNode *>(Vandal->getRchild());
    TreeNode *adjustLchild = const_cast<TreeNode *>(adjustNode->getLchild());
    // 将旋转结点的左孩子设置被破坏者的右孩子
    Vandal->setRchild(adjustNode->getLchild());
    // 如果存在右孩子
    if (adjustLchild)
    {
        // 更新其父节点
        adjustLchild->setParent(Vandal);
        // 更新结点标识
        adjustLchild->setChildFlag(false);
    }
    // 如果被破坏者有父节点
    TreeNode *VandalParent = const_cast<TreeNode *>(Vandal->getParent());
    if (VandalParent)
    {
        // 根据被破坏者的结点标识来判断它是其父节点的左孩子还是右孩子
        if (Vandal->getChildFlag())
            // 将旋转结点作为被破坏者的左孩子
            VandalParent->setLchild(adjustNode);
        else
            // 将旋转结点作为被破坏者的右孩子
            VandalParent->setRchild(adjustNode);
    }
    // 将被破坏者作为旋转结点的右孩子
    adjustNode->setLchild(Vandal);
    // 更新旋转结点的父节点
    adjustNode->setParent(Vandal->getParent());
    // 更新旋转结点的标识
    adjustNode->setChildFlag(Vandal->getChildFlag());
    // 更新被破坏者的结点标记
    Vandal->setChildFlag(true);
    // 更新被破坏者的父节点
    Vandal->setParent(adjustNode);
    // 更新被破坏者结点高度
    Vandal->updateHeight();
    // 更新旋转结点的高度
    adjustNode->updateHeight();
    // 如果父节点为空,说明左旋之后,adjustNode变成了根节点
    if (adjustNode->getParent() == nullptr)
        // 更新根节点
        this->root = adjustNode;
}
// LR型左右旋
template <class K, class V>
void AVLTree<K, V>::adjust_LR(TreeNode *Vandal)
{
    this->adjust_RR(const_cast<TreeNode *>(Vandal->getLchild()));
    this->adjust_LL(Vandal);
}
// RL型 右左旋
template <class K, class V>
void AVLTree<K, V>::adjust_RL(TreeNode *Vandal)
{
    this->adjust_LL(const_cast<TreeNode *>(Vandal->getRchild()));
    this->adjust_RR(Vandal);
}
// 打印结点
template <class K, class V>
void AVLTree<K, V>::PrintKey(const TreeNode *Node) const
{
    if (Node)
        std::cout << Node->getKey() << ' ';
    else
        std::cout << "NULL ";
}

template <class K, class V>
void AVLTree<K, V>::insert(const K &Key, const V &Value)
{

    // 创建新结点
    auto newNode = TreeNode::createNode(Key, Value);
    if (newNode == nullptr)
        return;
    // 如果头结点为空,则作为头结点插入,否则进行递归
    if (this->root == nullptr)
        this->rootInsert(newNode);

    else
        this->recursionInsert(this->root, newNode);

    // 更新高度
    this->update(this->root);
}

template <class K, class V>
void AVLTree<K, V>::insert(const TreeNode *NewNode)
{

    // 如果头结点为空,则作为头结点插入,否则进行递归
    if (this->root == nullptr)
        this->rootInsert(const_cast<TreeNode *>(NewNode));

    else
        this->recursionInsert(this->root, const_cast<TreeNode *>(NewNode));

    // 更新高度
    this->update(this->root);
}

template <class K, class V>
void AVLTree<K, V>::insert(const std::vector<std::pair<K, V>> &vNode)
{
    for (int i = 0; i < vNode.size(); ++i)
        this->insert(vNode[i].first, vNode[i].second);
}
// 插入子树
template <class K, class V>
void AVLTree<K, V>::insert(const AVLTree *SubTree)
{
    this->insertSubTree(SubTree->root);
}

template <class K, class V>
void AVLTree<K, V>::insertSubTree(const TreeNode *SubTree)
{
    // 子树为空直接返回
    if (SubTree == nullptr)
        return;
    // 将子树结点递归插入
    insertSubTree(SubTree->getLchild());
    insertSubTree(SubTree->getRchild());
    // 清空原先树结点指针数据
    const_cast<TreeNode *>(SubTree)->setParent(nullptr);
    const_cast<TreeNode *>(SubTree)->setLchild(nullptr);
    const_cast<TreeNode *>(SubTree)->setRchild(nullptr);
    // 插入结点
    this->insert(SubTree);
}

template <class K, class V>
void AVLTree<K, V>::clear(TreeNode *Root)
{
    if (Root == nullptr)
        return;
    this->clear(const_cast<TreeNode *>(Root->getLchild()));
    this->clear(const_cast<TreeNode *>(Root->getRchild()));
    delete Root;
    this->nodeSize--;
}
// 树是否为空
template <class K, class V>
bool AVLTree<K, V>::isEmpty() const
{
    return this->root == nullptr;
}
// 统计叶子结点个数
template <class K, class V>
inline void AVLTree<K, V>::statisticsLeafNode(const TreeNode *Root, int *Size) const
{
    if (Root == nullptr)
        return;
    // 没有左右孩子则是叶子结点
    if (Root->getLchild() == nullptr && Root->getRchild() == nullptr)
        (*Size)++;
    // 递归遍历
    this->statisticsLeafNode(Root->getLchild(), Size);
    this->statisticsLeafNode(Root->getRchild(), Size);
}
// 删除结点
template <class K, class V>
void AVLTree<K, V>::remove(const K &Key)
{
    // 获取被删除结点
    TreeNode *node = this->query(this->root, Key);
    // 结点存在则进行删除操作
    if (node)
    {
        // 获取删除结点左右子树,父节点
        TreeNode *deleteNodeLchild = const_cast<TreeNode *>(node->getLchild());
        TreeNode *deleteNodeRchild = const_cast<TreeNode *>(node->getRchild());
        TreeNode *deleteNodeParent = const_cast<TreeNode *>(node->getParent());

        // 根结点
        if (node->getParent() == nullptr)
        {
            // 获取上位结点
            TreeNode *replaceNode = deleteNodeLchild;
            if (replaceNode != nullptr)
            {
                // 将上位结点作为根结点
                this->root = replaceNode;
                // 上位结点的父节点置空
                replaceNode->setParent(nullptr);
                // 将根结点的右子树插入到上位节点的右子树中
                bool stop = false;
                replaceNode->insertTree(replaceNode, deleteNodeRchild, false, &stop);
            }
            else
            {
                // 上位结点为空说明该树只有右孩子,而且只有一个右孩子结点,其右孩子还没有左右子树
                //  将删除结点的右孩子作为根结点
                this->root = deleteNodeRchild;
                deleteNodeRchild->setParent(nullptr);
            }

            // 删除结点
            delete node;

            // 更新高度
            this->update(this->root);
            // 结点个数减一
            this->nodeSize--;
            return;
        }

        // 判断删除结点是左孩子还是右孩子
        if (node->getChildFlag())
        {

            // 获取上位结点
            TreeNode *replaceNode = deleteNodeRchild;
            if (replaceNode != nullptr)
            {
                // 将上位结点作为删除结点的父节点的左孩子
                replaceNode->setParent(deleteNodeParent);
                deleteNodeParent->setLchild(replaceNode);
                // 修改上位结点标识
                replaceNode->setChildFlag(node->getChildFlag());
                bool stop = false;
                // 将删除节点的左子树链接到上位结点的左子树下,更新其父节点
                replaceNode->insertTree(replaceNode, deleteNodeLchild, true, &stop);
            }
            else // 删除结点的父节点的左孩子指针置为空
                deleteNodeParent->setLchild(nullptr);

            // 删除结点
            delete node;

            // 更新高度
            this->update(this->root);
        }
        // 右孩子
        else if (!node->getChildFlag())
        {
            // 获取上位结点
            TreeNode *replaceNode = deleteNodeLchild;
            if (replaceNode != nullptr)
            {
                // 将上位结点作为删除结点的父节点的右孩子
                replaceNode->setParent(deleteNodeParent);
                deleteNodeParent->setRchild(replaceNode);
                // 修改上位结点标识
                replaceNode->setChildFlag(node->getChildFlag());
                bool stop = false;
                // 将删除节点的右子树链接到上位结点的右子树下,更新其父节点
                replaceNode->insertTree(replaceNode, deleteNodeRchild, false, &stop);
            }
            else
                // 删除结点的父节点的右孩子指针置为空
                deleteNodeParent->setRchild(nullptr);
            // 删除结点
            delete node;

            // 更新高度
            this->update(this->root);
        }

        // 结点个数减一
        this->nodeSize--;
    }
    else
        std::cerr << "键值不存在,无法删除" << std::endl;
}
// 前序遍历
template <class K, class V>
void AVLTree<K, V>::preorderTraversal() const
{
    this->preorderTraversal(this->root);
}
// 中序遍历
template <class K, class V>
inline void AVLTree<K, V>::middleTraversal() const
{
    this->middleTraversal(this->root);
}
// 后续遍历
template <class K, class V>
inline void AVLTree<K, V>::afterorderTraversal() const
{
    this->afterorderTraversal(this->root);
}
// 层次遍历
template <class K, class V>
void AVLTree<K, V>::hierarchyTraversal() const
{
    std::deque<TreeNode *> Queue;
    Queue.push_front(this->root);
    while (Queue.size() > 0)
    {
        TreeNode *Node = Queue.front();
        if (Node)
        {
            std::cout << "键值:" << Node->getKey() << ' ';
            std::cout << "值:" << Node->getValue() << ' ';
            std::cout << "高度:" << Node->getHeight() << std::endl;

            Queue.push_back(const_cast<TreeNode *>(Node->getLchild()));
            Queue.push_back(const_cast<TreeNode *>(Node->getRchild()));
        }
        else
        {
            std::cout << "NULL" << std::endl;
        }
        Queue.pop_front();
    }
}
// 更新结点值
template <class K, class V>
void AVLTree<K, V>::updateValue(const V &FindKey, const V &NewValue)
{
    TreeNode *node = this->query(this->root, FindKey);
    if (node)
        node->setValue(NewValue);

    else
        std::cerr << "键值不存在,无法更新" << std::endl;
}
// 查找与键值所匹配的结点,找到返回该结点,否则返回空指针
template <class K, class V>
const typename AVLTree<K, V>::TreeNode *AVLTree<K, V>::queryNode(const K &Key) const
{
    return this->query(this->root, Key);
}

template <class K, class V>
void AVLTree<K, V>::clear()
{
    if (this->root == nullptr)
        return;
    this->clear(this->root);
    this->root = nullptr;
}

template <class K, class V>
int AVLTree<K, V>::size() const
{
    return this->nodeSize;
}

template <class K, class V>
int AVLTree<K, V>::leafNodeSize() const
{
    int size = 0;
    this->statisticsLeafNode(this->root, &size);
    return size;
}

template <class K, class V>
int AVLTree<K, V>::notLeafNodeSize() const
{
    return this->nodeSize - this->leafNodeSize();
}

template <class K, class V>
inline int AVLTree<K, V>::height() const
{
    return this->root->getHeight();
}

template <class K, class V>
inline int AVLTree<K, V>::depth() const
{
    return this->root->getHeight();
}

#endif

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值