无序的问题

时间:2011-06-01 17:03:55

标签: c++ set unordered-set

任何人都可以解释一个无序集是如何工作的吗?我也不确定一套是如何工作的。我的主要问题是它的查找功能的效率如何。

例如,这个总的大O运行时间是多少?

    vector<int> theFirst;
    vector<int> theSecond;
    vector<int> theMatch;

    theFirst.push_back( -2147483648 );
    theFirst.push_back(2);
    theFirst.push_back(44);


    theSecond.push_back(2);
    theSecond.push_back( -2147483648 );
    theSecond.push_back( 33 );


    //1) Place the contents into a unordered set that is O(m). 
    //2) O(n) look up so thats O(m + n). 
    //3) Add them to third structure so that's O(t)
    //4) All together it becomes O(m + n + t)
    unordered_set<int> theUnorderedSet(theFirst.begin(), theFirst.end());

    for(int i = 0; i < theSecond.size(); i++) 
    {
        if(theUnorderedSet.find(theSecond[i]) != theUnorderedSet.end()) 
        {
        theMatch.push_back( theSecond[i] );
        cout << theSecond[i];
        }
   }

2 个答案:

答案 0 :(得分:4)

unordered_set和所有其他unordered_数据结构都使用哈希,如@Sean所述。散列涉及用于插入的摊销的恒定时间,并且接近于用于查找的恒定时间。哈希函数本质上需要一些信息并从中生成一个数字。在某种意义上,它是一个函数,相同的输入必须产生相同的输出。但是,不同的输入可能会导致相同的输出,从而导致所谓的碰撞。查找将保证是“完美哈希函数”的恒定时间,即没有冲突的查询。实际上,输入数字来自您存储在结构中的元素(比如它的值,它是基本类型)并将其映射到数据结构中的某个位置。因此,对于给定的键,该函数将您带到存储元素的位置,而不需要任何遍历或搜索(为简单起见忽略此处的冲突),因此需要恒定的时间。这些结构有不同的实现(开放寻址,链接等)。请参阅hash tablehash function。我还推荐Skiena的The Algorithm Design Manual第3.7节。现在,关于big-O复杂性,你是正确的,你有O(n)+ O(n)+ O(重叠的大小)。由于重叠不能大于m和n中的较小者,因此总体复杂度可以表示为O(kN),其中N在m和n之间最大。所以,O(N)。同样,这是“最佳情况”,没有碰撞,并且具有完美的散列效果。

另一方面,

setmulti_set使用二叉树,因此插入和查找通常为O(logN)。散列结构与二叉树的实际性能将取决于N,因此最好尝试这两种方法并在实际运行场景中对其进行分析。

答案 1 :(得分:2)

所有std :: unordered _ *()数据类型都使用哈希来执行查找。看看Boost关于这个主题的文档,我想你会很快得到一个理解。

http://www.boost.org/doc/libs/1_46_1/doc/html/unordered.html