AVL tree dictionary

AVL tree dictionary

本文关键字:dictionary tree AVL      更新时间:2023-10-16

到目前为止,我已经制定了一个攻击计划,看看我如何才能做到这一点,这就是我的计划:

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

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

void insert (String word) -插入字典中不存在的单词,否则更新。

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

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

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

我有我想做的事情的概念,我了解AVL树是如何工作的。但是当我真正写代码的时候,我完全卡住了,有人能帮我开始吗?

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

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

/*
 * 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;
}

一旦你有一个简单的二叉树工作和测试,重新实现插入函数来执行平衡,这是AVL算法的核心。

从了解AVL树的不变量开始:

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

我建议参考维基百科上的AVL树插入图。它说明了您需要实现的四种旋转以及需要它们的位置。

当节点的平衡因子超出range—换句话说,当左子树和右子树的高度差大于1时,需要进行旋转。

如何确定节点的平衡因子?好吧,下面任何一个都可以:

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

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

为了明确"高度"answers"平衡系数"的含义,这里有计算它们的函数:

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);
}

计算如何增量地更新高度或平衡因子将涉及纸、铅笔、简单代数和常识。

我希望这对你有帮助!