AVL树字典

5 c++ avl-tree visual-studio-2010 visual-c++

到目前为止,我一直在制定一个攻击计划,看看我如何能够做到这一点,这就是我所拥有的:

bool isEmpty() const - 如果为空则返回true,否则返回false

int getSize() - 返回字典中存储的单词数

void insert (String word) - 如果尚未存在,则将单词插入字典,否则更新.

boolfind(String word, WordNode & x) - 如果单词存在则返回true并将数据放在x中.

void printSorted() - 以字典顺序打印树中的单词(指定)

void remove (String word) - 实现节点的延迟删除

我有我想要做的概念,我理解AVL树是如何工作的.但是在实际编写代码时我完全陷入困境,任何人都可以帮助我开始吗?

Joe*_*ams 2

首先实现一个简单的二叉树(即,没有平衡),以及相应的程序来计算文件中的单词数。让它工作起来,这样你就有了可以测试的东西。现在先不要担心平衡问题;这是真正困难的部分。

这是一个简单二叉树的插入函数(未经测试):

/*
 * Insert a new key into a binary tree, or find an existing one.
 *
 * Return the new or existing node whose key is equal to the one requested.
 * Update *node with the new (sub)tree root.
 */
Node *insert(Node **node, String key)
{
    if (*node == NULL) {
        *node = new Node(key);
        return *node;
    }

    if (key < (*node)->key)
        return insert(&(*node)->left, key);

    if (key > (*node)->key)
        return insert(&(*node)->right, key);

    return *node;
}
Run Code Online (Sandbox Code Playgroud)

一旦你有了一个简单的二叉树并进行了测试,就可以重新实现插入函数来执行平衡,这是 AVL 算法的核心。

首先了解 AVL 树的不变量:

  • 任何节点的平衡因子(左子节点的高度与右子节点的高度之差)为 -1、0 或 +1。
  • 中序遍历产生字典顺序。

我建议参考维基百科上的AVL树插入图。它说明了您需要实施的四次轮换以及需要它们的位置。

当节点的平衡因子超出范围时,即左子树和右子树的高度差大于 1 时,就需要进行旋转。

如何确定节点的平衡因子?那么,以下任何一项都可以:

  1. 向 Node 结构添加一个height成员,并通过从左子节点的高度中减去右子节点的高度来确定任何给定节点的平衡因子。
  2. balance向 Node 结构添加一个成员。这可能有点难以弄清楚,但它会产生更简单的代码(我认为)。
  3. 通过遍历计算树的高度和平衡。这是低效的,以至于违背了 AVL 的目的。然而,它更容易理解并且更不易出现错误。

我建议从第三种方法开始,这样您就可以更快地测试您的平衡代码。

为了澄清“高度”和“平衡系数”的含义,以下是计算它们的函数:

int height(Node *node)
{
    if (node == NULL)
        return -1;
    return std::max(height(node->left), height(node->right)) + 1;
}

int balanceFactor(Node *node)
{
    assert(node != NULL);
    return height(node->right) - height(node->left);
}
Run Code Online (Sandbox Code Playgroud)

弄清楚如何逐步更新高度或平衡系数将涉及纸、铅笔、简单代数和常识。

我希望这有帮助!