更改二进制搜索树以平衡

时间:2017-12-08 23:29:17

标签: java tree binary-tree binary-search-tree

我刚学会了如何创建二进制搜索数据结构,该结构将用于存储字典中的数千个单词。我得到的问题是,计算添加和删除数据需要很长时间。通常在199263ms或200秒内计算100000字。我被告知,拥有一棵可以自我平衡的树将提高效率并使操作更快。

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

如果有人可以就如何提高树效率以及如何在java中实现平衡树方面给出建议,那将会很有帮助。

2 个答案:

答案 0 :(得分:1)

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

(来自Wikipedia :)

  
      
  1. 每个节点都是红色或黑色。

  2.   
  3. 根是黑色的。

  4.   
  5. 所有叶子(NIL)都是黑色。

  6.   
  7. 如果节点为红色,则其子节点均为黑色。

  8.   
  9. 从给定节点到其任何后代NIL节点的每条路径   包含相同数量的黑色节点。

  10.   

要开始实施红黑树,我建议在github上查看 this example implementation,并阅读红色黑树的this explanation

答案 1 :(得分:0)

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

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

通过扩展,如果读入的单词不需要放入树中并立即排序,Arrays.sort(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]);

根据您实际使用此数据的内容(仅查找表?),使用HashSet代替

可能会更快
Set<String> dict = new HashSet<String>();
BufferedReader reader = [...];
for(String line = reader.readLine(); line != null; line = reader.readLine())
    dict.add(line);