当前位置: 首页 > 知识库问答 >
问题:

将二叉搜索树更改为平衡

东郭淇
2023-03-14

我刚刚学习了如何创建二进制搜索数据结构,它将用于存储字典中的数千个单词。我遇到的问题是,统计添加和删除数据需要很长时间。通常为199263毫秒或200秒,计算100000个单词。有人告诉我,拥有一棵能够自我平衡的树将提高效率,使操作更快。

我的问题是如何使我的树自动平衡以使其高效。我通过消除重复的单词来使树的高度变短,从而做了一些小小的改进。

如果有人能给我一些建议,告诉我如何使树高效,以及如何在java中实现平衡树,将会很有帮助。

共有2个答案

严成礼
2023-03-14

为了平衡二叉树,只需构建一个新的二叉树,以更好的顺序添加元素可能会更容易

BinaryTree balance(BinaryTree tree)
{
    BinaryTree out = new BinaryTree();
    String[] values = tree.toArray(); //a sorted array
    for(int i = Integer.highestOneBit(values.length); i > 0; i >>= 1)
        for(int j = i; j <= values.length; j += i)
            out.add(values[j - 1]);
    return out;
}

通过扩展,如果读入的单词不需要立即放入树中并排序,数组。排序(Object[])可能会更快

List<String> wordList = new LinkedList<String>();
BufferedReader reader = [...];
for(String line = reader.readLine(); line != null; line = reader.readLine())
    wordList.add(line);
String[] words = wordList.toArray(new String[0]);
Arrays.sort(words);
BinaryTree tree = new BinaryTree();
for(int i = Integer.highestOneBit(words.length); i > 0; i >>= 1)
    for(int j = i; j <= words.length; j += i)
        out.add(words[j - 1]);

取决于您实际使用这些数据的目的(只是一个查找表?)使用哈希集可能会更快

Set<String> dict = new HashSet<String>();
BufferedReader reader = [...];
for(String line = reader.readLine(); line != null; line = reader.readLine())
    dict.add(line);
金毅
2023-03-14

你应该看看红/黑的树,它们是自我平衡的。节点除存储元素外还存储颜色,每次修改树时,都会重新平衡树,使其符合红/黑树的属性:

(来自维基百科:)

>

根是黑色的。

所有的叶子(无)都是黑色的。

如果一个节点是红色的,那么它的两个子节点都是黑色的。

每一个

为了开始实现红黑树,我建议大家看看github上的这个示例实现,并阅读红黑树的解释。

 类似资料:
  • 在上一节中,我们考虑构建一个二叉搜索树。正如我们所学到的,二叉搜索树的性能可以降级到 $$O(n)$$ 的操作,如 get 和 put ,如果树变得不平衡。在本节中,我们将讨论一种特殊类型的二叉搜索树,它自动确保树始终保持平衡。这棵树被称为 AVL树,以其发明人命名:G.M. Adelson-Velskii 和E.M.Landis。 AVL树实现 Map 抽象数据类型就像一个常规的二叉搜索树,唯一

  • 在我们继续之前,我们来看看执行这个新的平衡因子要求的结果。我们的主张是,通过确保树总是具有 -1,0或1 的平衡因子,我们可以获得更好的操作性能的关键操作。 让我们开始思考这种平衡条件如何改变最坏情况的树。有两种可能性,一个左重树和一个右重树。 如果我们考虑高度0,1,2和3的树,Figure 2 展示了在新规则下可能的最不平衡的左重树。 Figure 2 看树中节点的总数,我们看到对于高度为0的

  • 我在研究二叉树。我找到了在树中插入节点的代码。这里“root”是类“TreeType”中结构类型的指针变量,作为“private member”。 在这个函数中,“根”是通过引用传递的,所以在“插入”函数中,“树”中的任何变化也会导致“根”的变化。如果我们再次调用插入函数,根将指向最后一个节点还是指向第一个节点?所以,根据我的说法,当它指向最后一个节点时,插入函数将不再工作。有人能帮忙吗?

  • 所以,我一直在研究平衡的二叉查找树。 我谷歌了一下,这是我的发现: 二叉树,其中每个节点的两个子树的深度相差 1 或更小(来自维基百科) 难道就不能把平衡二叉树定义为高度不超过ceil(log(n ^ 1)/log ^ 2)的树吗? 从这个答案来看,提问者似乎已经问了同样的事情,但是公认的答案通过举斐波纳契树的例子拒绝了这个想法。斐波纳契树不是平衡树,对吗?我认为回答者可能会与AVL树中平衡树的定

  • 我写了一个函数,如果给定的二叉树是二叉搜索树,则返回true,否则返回false。 我的功能对吗?

  • 现在我们已经证明保持 AVL树的平衡将是一个很大的性能改进,让我们看看如何增加过程来插入一个新的键到树。由于所有新的键作为叶节点插入到树中,并且我们知道新叶的平衡因子为零,所以刚刚插入的节点没有新的要求。但一旦添加新叶,我们必须更新其父的平衡因子。这个新叶如何影响父的平衡因子取决于叶节点是左孩子还是右孩子。如果新节点是右子节点,则父节点的平衡因子将减少1。如果新节点是左子节点,则父节点的平衡因子将