AVL树字典
Posted
技术标签:
【中文标题】AVL树字典【英文标题】:AVL tree dictionary 【发布时间】:2011-07-24 15:37:33 【问题描述】:到目前为止,我一直在制定一个攻击计划,看看我该如何去做,这就是我所拥有的:
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 树的工作原理。但是在实际编写代码时我完全卡住了,有人可以帮我开始吗?
【问题讨论】:
你可能不需要实现remove
。统计词频的任务不需要它。不过,请检查您的作业。
remove,就像 insert 一样需要显示 AVL 树在添加或删除某些内容时如何处理自身平衡。
AVL 树本身并没有“平衡自身”; insert
和 remove
函数根据需要执行平衡。根据我的经验,实施remove
就像重新实施insert
,但更难。如果您无论如何都需要实现remove
,请确保您有办法对其进行测试。
到目前为止你有什么?如果你展示你目前所拥有的,我可能会提供帮助。
【参考方案1】:
首先实现一个简单的二叉树(即没有平衡),以及相应的程序来计算文件中的单词。让它工作,所以你会有一些东西可以测试。暂时不要担心平衡;这是最难的部分。
这是一个简单二叉树的插入函数(未经测试):
/*
* 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 tree insertion diagram。它说明了您需要实施的四个轮换以及需要它们的位置。
当一个节点的平衡因子超出范围时——换句话说,当左子树和右子树之间的高度差大于1时,旋转是必要的。
如何确定节点的平衡因子?好吧,以下任何一种都可以:
-
将
height
成员添加到Node 结构,并通过从左孩子的高度减去右孩子的高度来确定任何给定节点的平衡因子。
将balance
成员添加到节点结构。这可能有点难以弄清楚,但它会产生更简单的代码(我认为)。
通过遍历计算树的高度和平衡。这是低效的,以至于它违背了 AVL 的目的。但是,它更易于理解且不易出错。
我建议从第 3 种方法开始,这样您就可以更快地测试您的平衡代码。
为了阐明“高度”和“平衡因子”的含义,以下是计算它们的函数:
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);
弄清楚如何逐步更新高度或平衡因素将涉及纸、铅笔、简单代数和常识。
我希望这会有所帮助!
【讨论】:
知道了,非常感谢您的帮助。让我朝着正确的方向前进,现在我几乎完成了。谢谢:)以上是关于AVL树字典的主要内容,如果未能解决你的问题,请参考以下文章