C++ set替換vector進行優化

文章目錄

    • demo
      • 代碼解釋:
    • 底層原理
      • 1. 二叉搜索樹基礎
      • 2. 紅黑樹的特性
      • 3. `std::set` 基于紅黑樹的實現優勢
      • 4. 插入操作
      • 5. 刪除操作
      • 6. 查找操作

demo

#include <iostream>
#include <set>int main() {// 創建一個存儲整數的std::setstd::set<int> mySet;// 插入元素mySet.insert(300);mySet.insert(1);mySet.insert(2);mySet.insert(3);  mySet.insert(3);  // 重復元素不會被插入mySet.insert(300);  // 重復元素不會被插入mySet.insert(300);  // 重復元素不會被插入// 輸出集合中的元素std::cout << "Set elements: ";for (auto it = mySet.begin(); it != mySet.end(); ++it){std::cout << *it << " ";}std::cout << std::endl;// 查找元素auto findIt = mySet.find(2);if (findIt != mySet.end()){std::cout << "Element 2 found in the set." << std::endl;} else{std::cout << "Element 2 not found in the set." << std::endl;}// 刪除元素mySet.erase(1);std::cout << "Set elements after erasing 1: ";for (auto it = mySet.begin(); it != mySet.end(); ++it){std::cout << *it << " ";}std::cout << std::endl;// 檢查集合是否為空if (mySet.empty()) {std::cout << "The set is empty." << std::endl;}else{std::cout << "The set is not empty." << std::endl;}// 獲取集合的大小std::cout << "The size of the set is: " << mySet.size() << std::endl;// 清除集合中所有內容mySet.clear();std::cout << "Set elements after clearing: ";for (auto it = mySet.begin(); it != mySet.end(); ++it){std::cout << *it << " ";}std::cout << std::endl;// 再次檢查集合是否為空if (mySet.empty()){std::cout << "The set is empty after clearing." << std::endl;} else {std::cout << "The set is not empty after clearing." << std::endl;}return 0;
}    

在這里插入圖片描述

代碼解釋:

  1. 創建集合:使用std::set<int> mySet;創建一個存儲整數的std::set
  2. 插入元素:通過insert方法向集合中插入元素,重復元素不會被插入。
  3. 遍歷集合:使用迭代器遍歷集合中的元素并輸出。
  4. 查找元素:使用find方法查找指定元素,如果找到則返回指向該元素的迭代器,否則返回end()
  5. 刪除元素:使用erase方法刪除指定元素。
  6. 檢查集合是否為空:使用empty方法檢查集合是否為空。
  7. 獲取集合大小:使用size方法獲取集合中元素的數量。

底層原理

在C++標準庫中,std::set 是一個關聯容器,用于存儲唯一的元素,并且這些元素會按照一定的順序排列(默認是升序)。它的底層通常基于紅黑樹(Red - Black Tree)這種自平衡二叉搜索樹(Self - Balancing Binary Search Tree)來實現

1. 二叉搜索樹基礎

二叉搜索樹(Binary Search Tree,BST)是一種二叉樹,對于樹中的每個節點,其左子樹中的所有節點的值都小于該節點的值,而右子樹中的所有節點的值都大于該節點的值。這種特性使得在二叉搜索樹中進行查找、插入和刪除操作的平均時間復雜度為 O ( l o g n ) O(log n) O(logn),其中 n n n 是樹中節點的數量。

2. 紅黑樹的特性

紅黑樹是一種自平衡的二叉搜索樹,它在每個節點上增加了一個存儲位來表示節點的顏色(紅色或黑色)。通過對任何一條從根到葉子的路徑上各個節點著色方式的限制,紅黑樹確保沒有一條路徑會比其他路徑長出兩倍,因而是接近平衡的。紅黑樹必須滿足以下五個性質:

  • 每個節點要么是紅色,要么是黑色。
  • 根節點是黑色。
  • 每個葉子節點(NIL節點,空節點)是黑色的。
  • 如果一個節點是紅色的,則它的兩個子節點都是黑色的。
  • 對每個節點,從該節點到其所有后代葉節點的簡單路徑上,均包含相同數目的黑色節點。

3. std::set 基于紅黑樹的實現優勢

  • 有序性:由于紅黑樹是一種二叉搜索樹,插入到 std::set 中的元素會根據元素的鍵值自動排序。例如,插入整數時會按照從小到大的順序排列。
  • 唯一性:在插入元素時,紅黑樹會進行比較,如果發現元素已經存在,則不會插入,保證了 std::set 中元素的唯一性。
  • 高效的查找、插入和刪除操作:紅黑樹的自平衡特性保證了樹的高度始終保持在 O ( l o g n ) O(log n) O(logn) 級別,因此查找、插入和刪除操作的時間復雜度都是 O ( l o g n ) O(log n) O(logn)

4. 插入操作

當向 std::set 中插入一個新元素時,底層的紅黑樹會執行以下步驟:

  • 按照二叉搜索樹的規則找到新元素應該插入的位置。
  • 將新元素插入到該位置,并將其顏色設置為紅色。
  • 檢查紅黑樹的性質是否被破壞,如果破壞了則通過一系列的顏色調整和旋轉操作來恢復紅黑樹的性質。

5. 刪除操作

當從 std::set 中刪除一個元素時,紅黑樹會執行以下步驟:

  • 按照二叉搜索樹的規則找到要刪除的節點。
  • 如果該節點有兩個子節點,則用其右子樹中的最小節點替換該節點,然后刪除右子樹中的最小節點。
  • 刪除節點后,檢查紅黑樹的性質是否被破壞,如果破壞了則通過一系列的顏色調整和旋轉操作來恢復紅黑樹的性質。

6. 查找操作

查找操作相對簡單,根據二叉搜索樹的特性,從根節點開始比較,如果要查找的元素值小于當前節點的值,則在左子樹中繼續查找;如果大于當前節點的值,則在右子樹中繼續查找;如果相等,則找到了該元素。由于紅黑樹的高度為 O ( l o g n ) O(log n) O(logn),因此查找操作的時間復雜度也是 O ( l o g n ) O(log n) O(logn)

綜上所述,std::set 基于紅黑樹實現,利用紅黑樹的特性保證了元素的有序性、唯一性以及高效的查找、插入和刪除操作。

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

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

相關文章

如何巧妙解決 Too many connections 報錯?

1. 背景 在日常的 MySQL 運維中&#xff0c;難免會出現參數設置不合理&#xff0c;導致 MySQL 在使用過程中出現各種各樣的問題。 今天&#xff0c;我們就來講解一下 MySQL 運維中一種常見的問題&#xff1a;最大連接數設置不合理&#xff0c;一旦到了業務高峰期就會出現連接…

QT的布局和彈簧及其代碼解讀

this指的是真正的當前正在顯示的窗口 main函數&#xff1a; Widget w是生成了一個主窗口&#xff0c;QT Designer是在這個主窗口里塞組件 w.show()用來展示這個主窗口 頭文件&#xff1a; namespace Ui{class Widget;}中的class Widget和下面的class Widget不是一個東西 Ui…

《AI大模型應知應會100篇》第52篇:OpenAI API 使用指南與最佳實踐

第52篇&#xff1a;OpenAI API 使用指南與最佳實踐 &#x1f4cc; 摘要 本文將帶你從零開始掌握 OpenAI API 的核心使用方法&#xff0c;涵蓋從基礎調用到高級功能的完整實戰路徑。通過詳細的代碼示例、圖文解析和可運行的 Python 腳本&#xff0c;幫助你快速上手 GPT-3.5、GP…

C#學習7_面向對象:類、方法、修飾符

一、類 1class 1)定義類 訪問修飾符class 類名{ 字段 構造函數&#xff1a;特殊的方法&#xff08;用于初始化對象&#xff09; 屬性 方法... } eg: public class Person { // 字段 private string name; private int a…

湖北理元理律師事務所:債務優化中的“生活保障”方法論

債務危機往往伴隨生活質量驟降&#xff0c;如何在還款與生存間找到平衡點&#xff0c;成為債務優化的核心挑戰。湖北理元理律師事務所基于多年實務經驗&#xff0c;提出“雙軌并行”策略&#xff1a;法律減負與生活保障同步推進。 債務優化的“溫度法則” 1.生存資金預留機制…

Jetpack Compose與Kotlin UI開發革命

Jetpack Compose + Kotlin:Android UI 開發的革命 簡介 Jetpack Compose 是 Google 推出的現代 Android UI 工具包,結合 Kotlin 語言,徹底改變了傳統 Android 開發的模式。過去,開發者依賴 XML 布局和命令式編程(如 findViewById 和手動更新視圖),導致代碼冗長且易出錯…

基于pyqt的上位機開發

目錄 安裝依賴 功能包含 運行結果 安裝依賴 pip install pyqt5 pyqtgraph pyserial 功能包含 自動檢測串口設備&#xff0c;波特率選擇/連接斷開控制&#xff0c;數據發送/接收基礎框架&#xff0c;實時繪圖區域&#xff08;需配合數據解析&#xff09; ""&q…

QT人工智能篇-opencv

第一章 認識opencv 1. 簡單概述 OpenCV是一個跨平臺的開源的計算機視覺庫&#xff0c;主要用于實時圖像處理和計算機視覺應用?。它提供了豐富的函數和算法&#xff0c;用于圖像和視頻的采集、處理、分析和顯示。OpenCV支持多種編程語言&#xff0c;包括C、Python、Java等&…

Python自學第5天:字符串相關操作

1.字符串運算符 作符描述字符串連接*重復輸出字符串[]通過索引獲取字符串中字符[ : ]截取字符串中的一部分&#xff0c;遵循左閉右開原則&#xff0c;str[0:2] 是不包含第 3 個字符的。in成員運算符 - 如果字符串中包含給定的字符返回 Truenot in成員運算符 - 如果字符串中不包…

RabbitMq(尚硅谷)

RabbitMq 1.RabbitMq異步調用 2.work模型 3.Fanout交換機&#xff08;廣播模式&#xff09; 4.Diret交換機&#xff08;直連&#xff09; 5.Topic交換機&#xff08;主題交換機&#xff0c;通過路由匹配&#xff09; 6.Headers交換機&#xff08;頭交換機&#xff09; 6…

分庫分表后復雜查詢的應對之道:基于DTS實時性ES寬表構建技術實踐

1 問題域 業務發展的初期&#xff0c;我們的數據庫架構往往是單庫單表&#xff0c;外加讀寫分離來快速的支撐業務&#xff0c;隨著用戶量和訂單量的增加&#xff0c;數據庫的計算和存儲往往會成為我們系統的瓶頸&#xff0c;業界的實踐多數采用分而治之的思想&#xff1a;分庫…

CVE-2024-4577:Windows 編碼錯誤

CVE-2024-4577是一個 PHP-CGI 漏洞,就是其中一種情況:雖然有這個版本,但由于 PHP 經常被反向移植,因此無法可靠地使用。 這篇博文詳細介紹了如何研究 CVE-2024-4577 以及當前用于檢測它的方法。 CVE-2024-4577 CVE-2024-4577 是 Windows 版 PHP 安裝中的一個高危漏洞,會…

NetBox Docker 全功能部署方案(Ubuntu 22.04 + Docker)

環境準備 檢查操作系統版本&#xff1a; 本方案使用 Ubuntu 22.04&#xff0c;并在 VMware 虛擬機中運行。通過以下命令檢查系統版本&#xff1a; lsb_release -a 如果未安裝 Ubuntu 22.04&#xff0c;請下載并安裝一個全新的系統。 更新系統軟件源&#xff1a; 更新軟件包列表…

DeepSeek Copilot idea插件推薦

&#x1f30c; DeepSeek Copilot for IntelliJ IDEA 讓 AI 成為你的編程副駕駛&#xff0c;極速生成單元測試 & 代碼注釋驅動開發&#xff01; &#x1f680; 簡介 DeepSeek Copilot 是一款為 IntelliJ IDEA 打造的 AI 編程助手插件&#xff0c;它能夠智能分析你的代碼邏輯…

QT中的JSON

1.JSON的兩種數據格式 JSON有兩種數據格式:JSON對象和JSON數組 JSON數組&#xff1a; JSON數組格式&#xff1a;[元素1&#xff0c;元素2&#xff0c;元素3&#xff0c;......元素n] JSON數組中的元素可以是同一類型&#xff0c;也可以使不同類型&#xff0c;可以嵌套JSON數組…

詳細剖析傳輸層協議(TCP和UDP)

詳細講解傳輸層的網絡協議&#xff0c;為什么TCP是可靠連接協議&#xff0c;憑什么能做到不丟包&#xff0c;有哪些機制保證可靠呢&#xff1f; TCP/UDP UDPTCP**三次握手和四次揮手****滑動窗口****擁塞控制**&#xff08;socket套接字&#xff09;**listen的第二個參數** UD…

數據可視化:藝術與科學的交匯點,如何讓數據“開口說話”?

數據可視化&#xff1a;藝術與科學的交匯點&#xff0c;如何讓數據“開口說話”&#xff1f; 數據可視化&#xff0c;是科技與藝術的結合&#xff0c;是讓冰冷的數字變得生動有趣的橋梁。它既是科學——講究準確性、邏輯性、數據處理的嚴謹性&#xff1b;又是藝術——強調美感…

解決使用lettuce連接Redis超時的問題(tcpUserTimeout 參數失效問題)

問題背景 lettuce 連接Redis的主從實例&#xff0c;當主節的主機異常下電重啟后&#xff0c;由于沒有發送RST 包&#xff0c;導致 lettuce 一直在復用之前的TCP鏈接&#xff0c;然后會出現連接超時的情況。一直出現io.lettuce.core.RedisCommandTimeoutException: Command tim…

如何使用python保存字典

在Python中&#xff0c;可以通過多種方式將字典&#xff08;dict&#xff09;保存到文件中&#xff0c;并能夠隨時讀取恢復。以下是幾種常見的方法&#xff1a; 1. 使用 json 模塊&#xff08;推薦&#xff09; 適用場景&#xff1a;需要人類可讀的文件格式&#xff0c;且數據不…

SQL 與 Python:日期維度表創建的不同選擇

文章目錄 一、日期維度表概述日期維度表結構 二、使用 SQL 創建日期維度表2.1 表結構設計2.2 數據插入2.3 SQL 創建方式的優勢與局限 三、使用 Python 創建日期維度表3.1 依賴庫引入3.2 代碼實現3.3 Python 創建方式的優勢與局限 四、應用場景與選擇建議4.1 應用場景4.2 選擇建…