C++ 如何找到一个好的点开始二叉搜索树

C++ 如何找到一个好的点开始二叉搜索树,c++,binary-search-tree,fstream,C++,Binary Search Tree,Fstream,我有一个包含大量单词的文本文件,20K+,但是它们都是按字母顺序排列的,现在假设你得到一个随机文件,你不知道它有多大,你如何找到一个好的起点来创建一个平衡的树?注意:我在C++中做这个。谢谢你的建议!我现在是这样读的: template <typename T> int BST<T>::loadFromFile(string filename) { int count = 0; string tempdata; ifstream fin(filen

我有一个包含大量单词的文本文件,20K+,但是它们都是按字母顺序排列的,现在假设你得到一个随机文件,你不知道它有多大,你如何找到一个好的起点来创建一个平衡的树?注意:我在C++中做这个。谢谢你的建议!我现在是这样读的:

template <typename T>
int BST<T>::loadFromFile(string filename)
{
    int count = 0;
    string tempdata;
    ifstream fin(filename);
    if(!fin)
{
    cout<< "Error: Could no open file\n";
    count--;
}
while(fin)
{
    fin>>tempdata;
    if(fin)
    {
        insertEntry(tempdata);
        cout<<"Word: "<<tempdata<<" Count:"<<count<<endl;
        count++;

    }
}
fin.close();
return count;
}//end of loadFromFile() function
模板
int BST::loadFromFile(字符串文件名)
{
整数计数=0;
字符串数据;
ifstream-fin(文件名);
如果(!fin)
{
cout>tempdata;
国际单项体育联合会(财务)
{
插入(临时数据);
库特
你如何找到一个好的起点,使一个良好的平衡
树

将文件读入元素向量v

排序向量v

a) 从中间加载单个树元素=(大小/2)

b) 从左半部分递归加载(v[0]…v[middle]-1)

c) 从右半部分递归加载(v[middle+1]…v[size()]

删除向量


2014-08-02更新

我想我会提供一些关于以“良好”顺序将已排序向量内容传输到二叉树的“递归”性质的见解。一种非随机顺序,完成后应使(简单二叉树)保持良好平衡

最坏的情况下,插入可能会导致O(n)搜索

平衡(简单)二叉树是O(logn)

此外,使用

 std::stable_sort(v.begin(), v.end());
 // this resulted in a lexicographic sort, probably what you want



 vector    after sort: 
        sort duration: 25,273 us
          total bytes: 152,729
       sizeof(vector): 12
        vector.size(): 32767
存在更复杂的替代方案-AVL树、红黑树等。另一方面,有了这些,您可能会放弃向量和排序


(使用的性能结果-O0)

特别是如果您的数据已经排序,您最好不要使用树,而是将单词读入向量并执行二进制搜索以找到所需的单词。二进制搜索具有O(log(n))复杂性,就像二叉树一样。构建向量具有O(n)复杂性vs O(n*log(n))对树进行排序。即使未对单词进行排序,对数组进行排序也可能比将所有单词插入到树中的效果更好。使用排序向量进行搜索的优点是内存开销更小,并且对缓存更友好,从而获得更高的性能。

20000不是一个很大的数量。存在一个O(N)从已排序的输入构建平衡树的算法。你的问题仍然不清楚。等等,随机文件是否仍在排序?我想不是。是的,我是说如果有人给我一个较短的文件,我不知道其长度。我如何从该文件中找到可能的最佳根?为什么?平衡树算法为你提供了一个合理的近似值不管怎样,只要通过正常的构造就可以找到一个最佳的根。你想在这里解决什么问题?很抱歉我的解释不好,下面的答案在某种程度上解决了这个问题。如果文件按字母顺序排序,那么我的二元搜索树将只是数据的一条对角线,而不是一棵树。因此,它在搜索d时效率不高ata.这不会在找到任何正确的东西时去掉常数O(N)?它实际上会帮助保持真实?这难道不会给我一个二元搜索树的^型形状吗?@StingRay21-二元树的“搜索”是O(logn)。(不是常数)。它平均也是:O(N)空格,O(logn)插入,O(logn)删除,最坏的情况是:O(N)空格,O(n) insert,O(n)delete。我同意树的形状将是一个倒v形,值范围的中间位于树的顶部。32K元素的树高度是15,因此递归构建只有15深。
  buildTree from vec: 
            duration: 132,013 us
         total bytes: 152,729
 std::stable_sort(v.begin(), v.end());
 // this resulted in a lexicographic sort, probably what you want



 vector    after sort: 
        sort duration: 25,273 us
          total bytes: 152,729
       sizeof(vector): 12
        vector.size(): 32767