📜  C++ STL中的set vs unordered_set

📅  最后修改于: 2021-05-30 03:00:44             🧑  作者: Mango

先决条件:在C++中设置,在C++中为unordered_set

差异:

|     set             | unordered_set
---------------------------------------------------------
Ordering        | increasing  order   | no ordering
                | (by default)        |

Implementation  | Self balancing BST  | Hash Table
                | like Red-Black Tree |  

search time     | log(n)              | O(1) -> Average 
                |                     | O(n) -> Worst Case

Insertion time  | log(n) + Rebalance  | Same as search
                      
Deletion time   | log(n) + Rebalance  | Same as search

何时使用设定

  • 我们需要有序的数据。
  • 我们将不得不打印/访问数据(按排序顺序)。
  • 我们需要元素的前任/后继。
  • 由于set是有序的,因此我们可以在set元素上使用binary_search(),lower_bound()和upper_bound()之类的函数。这些函数不能在unordered_set()上使用。
  • 有关更多情况,请参见BST相对于哈希表的优势。

在以下情况下使用unordered_set

  • 我们需要保留一组不同的元素,并且不需要排序。
  • 我们需要单元素访问,即无遍历。

例子:

set:
Input  :  1, 8, 2, 5, 3, 9
Output :  1, 2, 3, 5, 8, 9

Unordered_set:
Input  : 1, 8, 2, 5, 3, 9
Output : 9 3 1 8 2 5 

如果要查看C++ STL中set和unordered_set的实现详细信息,请参见Set Vs Map。 Set允许按排序顺序遍历元素,而Unordered_set不允许按排序顺序遍历元素。

// Program to print elements of set
#include 
using namespace std;
  
int main()
{
    set s;
    s.insert(5);
    s.insert(1);
    s.insert(6);
    s.insert(3);
    s.insert(7);
    s.insert(2);
  
    cout << "Elements of set in sorted order: \n";
    for (auto it : s)
        cout << it << " ";
  
    return 0;
}
输出:
Elements of set in sorted order: 
1 2 3 5 6 7
// Program to print elements of set
#include 
using namespace std;
  
int main()
{
    unordered_set s;
    s.insert(5);
    s.insert(1);
    s.insert(6);
    s.insert(3);
    s.insert(7);
    s.insert(2);
  
    cout << "Elements of unordered_set: \n";
    for (auto it : s)
        cout << it << " ";
  
    return 0;
}
输出:
Elements of unordered_set: 
2 7 5 1 6 3

套装中的前任/后继
可以修改Set来查找前任或后继,而Unordered_set不允许查找前任/后继。

// Program to print inorder predecessor and inorder successor
#include 
using namespace std;
  
set s;
  
void inorderPredecessor(int key)
{
    if (s.find(key) == s.end()) {
        cout << "Key doesn't exist\n";
        return;
    }
  
    set::iterator it;
    it = s.find(key); // get iterator of key
  
    // If iterator is at first position
    // Then, it doesn't have predecessor
    if (it == s.begin()) {
        cout << "No predecessor\n";
        return;
    }
  
    --it; // get previous element
    cout << "predecessor of " << key << " is=";
    cout << *(it) << "\n";
}
  
void inorderSuccessor(int key)
{
    if (s.find(key) == s.end()) {
        cout << "Key doesn't exist\n";
        return;
    }
  
    set::iterator it;
    it = s.find(key); // get iterator of key
    ++it; // get next element
  
    // Iterator points to NULL (Element does
    // not exist)
    if (it == s.end())
    {
        cout << "No successor\n";
        return;
    }
    cout << "successor of " << key << " is=";
    cout << *(it) << "\n";
}
  
int main()
{
    s.insert(1);
    s.insert(5);
    s.insert(2);
    s.insert(9);
    s.insert(8);
  
    inorderPredecessor(5);
    inorderPredecessor(1);
    inorderPredecessor(8);
    inorderSuccessor(5);
    inorderSuccessor(2);
    inorderSuccessor(9);
  
    return 0;
}
输出:
predecessor of 5 is=2
No predecessor
predecessor of 8 is=5
successor of 5 is=8
successor of 2 is=5
No successor
要从最佳影片策划和实践问题去学习,检查了C++基础课程为基础,以先进的C++和C++ STL课程基础加上STL。要完成从学习语言到DS Algo等的更多准备工作,请参阅“完整面试准备课程”