std::set (C++)

std::set

  • 1. 概述
    • 定義
    • 特點
  • 2. 內部實現
  • 3. 性能特征
  • 4. 常用 API
  • 5. 使用示例
  • 6. 自定義比較器
  • 7. 注意事項與優化
  • 8. 使用建議

1. 概述

定義

template<class Key,class Compare = std::less<Key>,class Allocator = std::allocator<Key>
>
class std::set;

特點

  • 有序:所有元素按嚴格弱序(由 Compare 決定)排列,不保證相同鍵的重復出現(鍵唯一)。

  • 唯一鍵:插入時如果集合中已有相同元素,不會增加新的節點。

  • 底層結構:通常基于紅黑樹(balanced binary search tree)實現。

2. 內部實現

  1. 紅黑樹

    • 平衡二叉查找樹,保證從根到任一葉子路徑的“黑色節點數”相同,從而令樹高度為 O(log n)。
  2. 節點結構

    • 每個節點存儲:
      • 元素值 Key
      • 左/右子指針和父指針
      • 一個顏色標記(紅或黑)
  3. 拷貝與移動

    • 拷貝時會對整棵樹進行深拷貝;移動構造則接管底層指針,無需逐節點復制。

3. 性能特征

操作平均復雜度最壞復雜度備注
insertO(log n)O(log n)包括查找插入位置與調整平衡
eraseO(log n)O(log n)按鍵刪除時需旋轉與重著色
findO(log n)O(log n)
clearO(n)O(n)釋放所有節點
遍歷O(n)O(n)中序遍歷即可
  • 內存開銷:

    • 每個節點需存儲三個指針(左右、父)和一個顏色字段,相比哈希表更緊湊但比 std::vector 等順序容器要高。
  • 迭代器失效規則:

    • 插入和刪除會使僅被刪除的節點的迭代器失效,其他節點迭代器保持有效。

4. 常用 API

// 構造與析構
std::set<Key> s1;                             // 默認構造
std::set<Key> s2({k1, k2, k3});               // 初始化列表
std::set<Key, Compare> s3(comp);              // 指定比較器// 大小與容量
bool empty() const noexcept;
size_t size() const noexcept;
size_t max_size() const noexcept;// 元素訪問
iterator find(const Key& key);
size_t count(const Key& key) const;           // 要么 0,要么 1// 插入
std::pair<iterator,bool> insert(const Key& key);
iterator insert(iterator hint, const Key& key);
template<class... Args>
std::pair<iterator,bool> emplace(Args&&... args);// 刪除
size_t erase(const Key& key);
iterator erase(iterator pos);
iterator erase(iterator first, iterator last);// 遍歷
iterator begin() noexcept;
iterator end() noexcept;
const_iterator cbegin() const noexcept;
const_iterator cend() const noexcept;// 有序查詢
iterator lower_bound(const Key& key);         // ≥ key 的第一個位置
iterator upper_bound(const Key& key);         // > key 的第一個位置
std::pair<iterator,iterator> equal_range(const Key& key);// 比較器與分配器訪問
Compare key_comp() const;
Compare value_comp() const;                   // 同 key_comp
Allocator get_allocator() const noexcept;// 交換
void swap(std::set& other) noexcept;

5. 使用示例

#include <set>
#include <iostream>int main() {std::set<int> s;// 插入s.insert(3);s.emplace(1);s.insert({5, 2, 4});// 查找if (s.find(2) != s.end()) {std::cout << "2 存在\n";}// 遍歷(中序:1,2,3,4,5)for (int x : s) {std::cout << x << " ";}std::cout << "\n";// 有序查詢auto it = s.lower_bound(3);  // 指向 3std::cout << "lower_bound(3): " << *it << "\n";// 刪除s.erase(3);                  // 刪除值為 3 的節點// 范圍刪除s.erase(s.begin(), s.lower_bound(4)); // 刪除所有 <4 的元素// 清空s.clear();
}

6. 自定義比較器

當需要自定義排序規則(如降序或復合鍵)時,可提供自定義比較器:

struct Desc {bool operator()(int a, int b) const {return a > b;  // 降序}
};std::set<int, Desc> s_desc;  // 插入后,將按從大到小順序存儲

對于復合類型:

struct Person {std::string name;int age;
};struct ByAgeName {bool operator()(Person const& a, Person const& b) const {if (a.age != b.age) return a.age < b.age;return a.name < b.name;}
};// 年齡升序,若年齡相同則按名字升序
std::set<Person, ByAgeName> roster;

7. 注意事項與優化

  1. 避免不必要的拷貝

    • insert(const Key&) 會拷貝一次;若可移動,優先使用 insert(Key&&) 或 emplace()。
  2. hint 參數

    • insert(hint, key):若能提供一個接近正確位置的迭代器 hint,可將插入復雜度降到常數時間。
  3. 批量插入

    • 對初始化列表或范圍插入,建議先 reserve()(C++23 起支持)或構造時傳入范圍,以減少重平衡次數。
  4. 避免迭代器失效

    • 刪除或插入僅影響相關節點迭代器,其他迭代器保持有效。

8. 使用建議

  • 適用場景

    • 需要自動排序且元素唯一時,首選 std::set。
    • 需要查詢前驅/后繼、區間操作(lower_bound、upper_bound、中序遍歷)時非常方便。
  • 不適用場景

    • 需要允許重復鍵或多對一映射時,改用 std::multiset 或 std::map。
    • 對性能有極致要求且不在意順序時,可考慮 std::unordered_set(哈希實現,平均 O(1))。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/901954.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/901954.shtml
英文地址,請注明出處:http://en.pswp.cn/news/901954.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

SSM省市區三級聯動和三表聯查附帶數據庫

SSM省市區三級聯動和三表聯查 ------附帶數據庫碼云地址&#xff1a;https://gitee.com/Mr_ZKC/NO1 數據庫在項目中

曲棍球·棒球1號位

中國女子曲棍球隊曾涌現過馬弋博、李紅俠等優秀選手&#xff0c;但“李紅”這一名字可能為信息誤差。以下為您系統介紹曲棍球&#xff0c;并結合棒球進行對比分析&#xff1a; 曲棍球&#xff08;Hockey&#xff09;核心特點 運動形式 分為草地曲棍球&#xff08;夏季奧運會項…

12芯束裝光纖不同包層線顏色之間的排列順序

為什么光纖線必須按照以下顏色順序進行排序&#xff1f;這其實是為了防止光污染的問題&#xff0c;不同顏色在傳遞光時從包層表皮漏光傳感到梳妝的其它纖芯上&#xff0c;會有光污染的問題&#xff0c;而為了減少并防止光污染的現象&#xff0c;所以在光通信之中&#xff0c;需…

c++程序的打包編譯cmake+make

c打包編譯 1 在不用系統中打包介紹1.1 linux中打包c程序的2種方式1.2 windows中打包c程序1.3 cmakeNinja和cmakemake的兩種方式對比1.3.1 Ninja是什么&#xff08;可以認為是make工具的一個替代產品&#xff09;1.3.2 cmakeNinja可以用于linux和windows系統中&#xff0c;編譯效…

Spark on K8s 在 vivo 大數據平臺的混部實戰與優化

一、Spark on K8s 簡介 (一)定義與架構 Spark on K8s 是一種將 Spark 運行在 Kubernetes(K8s)集群上的架構,由 K8s 直接創建 Driver 和 Executor 的 Pod 來運行 Spark 作業。其架構如下。 Driver Pod:相當于 Spark 集群中的 Driver,負責作業的調度和管理,它會根據作業…

MDA測量數據查看器【內含工具和源碼地址】

一、工具介紹 MDA測量數據查看器用于顯示和分析以MDF格式提供的測量數據。 支持MDF3.3之前含MDF3.3的二進制格式&#xff0c;支持Vector CANape and ETAS Inca. Kvaser CAN Logger (MDF 3.2) 文件。 MDF (Measurement Data Format)是一種二進制文件&#xff0c;用來記錄、交換…

番外篇 | SEAM-YOLO:引入SEAM系列注意力機制,提升遮擋小目標的檢測性能

前言:Hello大家好,我是小哥談。SEAM(Squeeze-and-Excitation Attention Module)系列注意力機制是一種高效的特征增強方法,特別適合處理遮擋和小目標檢測問題。該機制通過建模通道間關系來自適應地重新校準通道特征響應。在遮擋小目標檢測中的應用優勢包括:1)通道注意力增強…

使用VHDL語言實現TXT文件的讀寫操作

使用FPGA進行圖像處理時&#xff0c;通常需要將TXT文件中的圖像數據讀出到TestBench中&#xff0c;并將仿真的結果寫入到TXT文件中&#xff0c;用于確認圖像處理的結果是否正確。 VHDL中TXT文件的讀寫操作如下所示&#xff0c; --------------------------------------------…

基于Redis的4種延時隊列實現方式

延時隊列是一種特殊的消息隊列&#xff0c;它允許消息在指定的時間后被消費。在微服務架構、電商系統和任務調度場景中&#xff0c;延時隊列扮演著關鍵角色。例如&#xff0c;訂單超時自動取消、定時提醒、延時支付等都依賴延時隊列實現。 Redis作為高性能的內存數據庫&#x…

GN ninja 工程化構建例程

文章目錄 1. 前言?2. 工程實例??2.1 工程目錄結構2.2 工程頂層.gn文件2.3 工具鏈配置.gn文件2.4 編譯配置.gn文件2.5 編譯目標配置.gn文件2.6 工程接口文件2.7 動態庫編譯.gn文件2.8 動態庫源文件2.9 靜態庫編譯.gn文件2.10 靜態庫源文件2.11 主程序編譯.gn文件2.12 主程序源…

基于亞博K210開發板——內存卡讀寫文件

開發板 亞博K210開發板 實驗目的 本實驗主要學習 K210 通過 SPI 讀寫內存卡文件的功能 實驗準備 實驗元件 開發板自帶的 TF 卡、LCD 顯示屏 &#xff08;提前準備好 FAT32 格式的TF 卡。TF 插入 TF 卡槽的時候注意方向&#xff0c;TF 卡的金手指那一面需要面向開發板&am…

51單片機實驗五:A/D和D/A轉換

一、實驗環境與實驗器材 環境&#xff1a;Keli&#xff0c;STC-ISP燒寫軟件,Proteus. 器材&#xff1a;TX-1C單片機&#xff08;STC89C52RC&#xff09;、電腦。 二、 實驗內容及實驗步驟 1.A/D轉換 概念&#xff1a;模數轉換是將連續的模擬信號轉換為離散的數字信…

C++ 常用的智能指針

C 智能指針 一、智能指針類型概覽 C 標準庫提供以下智能指針&#xff08;需包含頭文件 <memory>&#xff09;&#xff1a; unique_ptr&#xff1a;獨占所有權&#xff0c;不可復制&#xff0c; 可移動shared_ptr&#xff1a;共享所有權&#xff0c;用于引用計數weak_pt…

6.8.最小生成樹

一.復習&#xff1a; 1.生成樹&#xff1a; 對于一個連通的無向圖&#xff0c;假設圖中有n個頂點&#xff0c;如果能找到一個符合以下要求的子圖&#xff1a; 子圖中包含圖中所有的頂點&#xff0c;同時各個頂點保持連通&#xff0c; 而且子圖的邊的數量只有n-1條&#xff0…

Spring Boot 集成金蝶 API 演示

? Spring Boot 集成金蝶 API 演示&#xff1a;登錄 / 注銷 Cookie 保存 本文將通過 Spring Boot 完整實現一套金蝶接口集成模型&#xff0c;包括&#xff1a; ? 普通登錄? AppSecret 登錄? 注銷? Cookie 保存與復用 &#x1f4c5; 項目結構 src/ ├── controller/ │…

React 受控表單綁定基礎

React 中最常見的幾個需求是&#xff1a; 渲染一組列表綁定點擊事件表單數據與組件狀態之間的綁定 受控表單綁定是理解表單交互的關鍵之一。 &#x1f4cd;什么是受控組件&#xff1f; 在 React 中&#xff0c;所謂“受控組件”&#xff0c;指的是表單元素&#xff08;如 &l…

基于FPGA的AES加解密系統verilog實現,包含testbench和開發板硬件測試

目錄 1.課題概述 2.系統測試效果 3.核心程序與模型 4.系統原理簡介 4.1 字節替換&#xff08;SubBytes&#xff09; 4.2 行移位&#xff08;ShiftRows&#xff09; 4.3 列混合&#xff08;MixColumns&#xff09; 4.4 輪密鑰加&#xff08;AddRoundKey&#xff09; 4.…

6.5 GitHub監控系統實戰:雙通道采集+動態調度打造高效運維體系

GitHub Sentinel Agent 定期更新功能設計與實現 關鍵詞:GitHub API 集成、定時任務調度、Python 爬蟲開發、SMTP 郵件通知、系統穩定性保障 1. GitHub 項目數據獲取功能 1.1 雙通道數據采集架構設計 #mermaid-svg-ZHJIMXcMAyDHVhmV {font-family:"trebuchet ms",v…

Explorer++:輕量級高效文件管理器!!

項目簡介 Explorer 是一款專為Windows操作系統設計的輕量級且高效的文件管理器。作為Windows資源管理器的強大替代方案&#xff0c;它提供了豐富的特性和優化的用戶體驗&#xff0c;使得文件管理和組織變得更加便捷高效。無論是專業用戶還是普通用戶&#xff0c;都能從中受益&a…