【C++進階學習】第六彈——set和map——體會用C++來構建二叉搜索樹

set和map基礎:【C++進階學習】第五彈——二叉搜索樹——二叉樹進階及set和map的鋪墊-CSDN博客

前言:

在上篇的學習中,我們已經學習了如何使用C語言來實現二叉搜索樹,在C++中,我們是有現成的封裝好的類模板來實現二叉搜索樹的——set和map,這也是我們今天要講的重點

目錄

一、容器

二、set和multiset

一、set與multiset概述

二、set與multiset的基本操作

三、高級特性

四、set與multiset的選擇

三、map和multimap

1.?map與multimap的區別

2.?map與multimap的使用場景

3. 基本操作

4. 注意事項

5. 示例代碼

四、總結


一、容器

在前面,我們經常提到容器這個東西,比如stack、queue等許多類模板都稱之為容器,其實今天要講的set和map也是容器的一種,容器這個東西我會在下一章進行單獨講解,有興趣的可以關注一下

二、set和multiset

在C++標準模板庫(STL)中,setmultiset是兩種關聯容器,它們在處理有序集合數據時非常有用。

一、set與multiset概述

set?是一種關聯容器,它存儲唯一(不重復)的元素,并且這些元素會根據特定的排序規則自動排序。set內部通常采用紅黑樹實現,保證了元素的對數時間復雜度的插入、刪除和查找操作。

multiset?與set類似,但它允許存儲重復的元素。multiset同樣基于紅黑樹實現,其操作的時間復雜度特性與set相同。

二、set與multiset的基本操作

在使用set或multiset之前,需要包含相應的頭文件:

#include <set>
#include <multiset>

以下是一些基本操作:

  1. 構造函數
set<T> s; // 默認構造函數
multiset<T> ms; // 默認構造函數
// 可以通過比較函數和分配器進行自定義構造
  1. 插入元素
s.insert(key); // set插入元素
ms.insert(key); // multiset插入元素
  • insert?方法用于向set或multiset中添加元素,如果插入成功,set?的insert方法返回pair<iterator, bool>(這個東西后面會講),其中bool指示是否插入成功。
  • multiset?的insert方法返回指向插入元素的迭代器。
  1. 刪除元素
s.erase(key); // 刪除特定元素(set)
ms.erase(key); // 刪除特定元素(multiset)
// 刪除操作在multiset中會刪除所有匹配的元素
  1. 查找元素
auto it = s.find(key); // 查找元素(set)
auto it = ms.find(key); // 查找元素(multiset)
// find返回指向元素的迭代器,如果未找到則返回end()
  1. 統計元素個數
s.count(key); // set中元素個數(總是1或0)
ms.count(key); // multiset中元素個數(可能是大于0的整數)
  1. 大小和容量
s.size(); // 返回元素數量
ms.size(); // 返回元素數量
s.empty(); // 判斷是否為空
ms.empty(); // 判斷是否為空

三、高級特性

  1. 迭代器

set和multiset都提供迭代器,支持前向和后向遍歷。

for (auto it = s.begin(); it != s.end(); ++it) {// 遍歷set中的元素
}
  1. 排序規則

默認情況下,set和multiset使用小于操作符<進行排序,但可以通過自定義比較函數來改變排序規則。

struct CustomCompare {bool operator()(const T& a, const T& b) const {// 自定義比較邏輯}
};
set<T, CustomCompare> s; // 使用自定義比較函數
multiset<T, CustomCompare> ms; // 使用自定義比較函數
  1. 性能考慮

由于set和multiset基于二叉搜索樹實現,它們的插入、刪除和查找操作通常具有O(log n)的時間復雜度。

四、set與multiset的選擇

選擇使用set還是multiset取決于是否需要存儲重復元素。如果需要存儲唯一的元素集合,則應該使用set。如果允許集合中存在重復元素,那么應該選擇multiset。

三、map和multimap

在C++的STL(標準模板庫)中,mapmultimap是兩種關聯容器,它們用于存儲鍵值對。這些容器使用紅黑樹作為底層數據結構,以確保高效的插入、查找和刪除操作。

1.?mapmultimap的區別

  • 唯一性map存儲的是唯一鍵值對,即每個鍵只能對應一個值。而multimap允許相同的鍵對應多個值,提供了一種更靈活的數據存儲方式。
  • 排序:兩者都按照鍵的自然順序進行排序,通常為升序。可以通過自定義比較函數來改變排序規則。

2.?mapmultimap的使用場景

  • map通常用于需要確保鍵的唯一性且需要對鍵進行排序的場景。例如,統計不同類別的數據數量、實現字典等。
  • multimap則適用于需要處理多個值與相同鍵關聯的場景,如記錄用戶在不同時間段的登錄記錄。

3. 基本操作

下面這些操作與上面set和multiset的操作基本一致,就不再寫了

  • 構造與初始化:可以通過構造函數直接初始化mapmultimap,也可以使用std::make_mapstd::make_multimap輔助函數。自定義排序可以通過傳遞比較函數來實現。
  • 插入與刪除:使用insert方法插入鍵值對,erase方法刪除鍵值對。erase方法還可以用于刪除指定范圍內的元素。
  • 查找find方法用于查找鍵值對,返回指向匹配元素的迭代器;lower_boundupper_bound方法用于查找鍵的范圍,適用于處理多個相同鍵的值。

4. 注意事項

  • 迭代器的失效:刪除元素后,所有指向被刪除元素的迭代器都會失效。在迭代時,需要確保迭代器的有效性。
  • 鍵的類型:鍵的類型必須支持比較操作,通常需要有定義的比較運算符或提供一個比較函數。
  • 性能:插入、查找和刪除操作的時間復雜度為O(log n),基于紅黑樹的高效性。
  • 值類型:值的類型可以是任何類型,但通常選擇有意義的數據類型,如整型、浮點型或字符串等。

5. 示例代碼

#include <iostream>
#include <map>
#include <string>
using namespace std;int main() {// 使用map存儲唯一鍵值對map<string, int> fruitCounts = {{"apple", 10},{"banana", 15},{"cherry", 5}};// 使用multimap存儲多個值與相同鍵關聯multimap<string, int> logins = {{"Alice", 1001},{"Bob", 2001},{"Alice", 1003}};// 查找和打印map中的元素auto it = fruitCounts.find("banana");if (it != fruitCounts.end()) {cout << "Found banana: " << it->second << endl;}// 查找和打印multimap中的元素auto range = logins.equal_range("Alice");for (auto it = range.first; it != range.second; ++it) {cout << "Login for Alice: " << it->second << endl;}return 0;
}

運行結果:

四、總結

以上就是C++中set和map的全部內容,其實底層邏輯就是二叉搜索樹或者準確來說叫紅黑樹,其中有一些小的知識點會在下一節再提一下

感謝各位大佬觀看,創作不易,還請各位大佬點贊支持一下!!!

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

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

相關文章

第二講 數據結構

#數組模擬鏈表 #include <iostream> using namespace std; const int N 100010; int head ,e[N], ne[N],idx; //ne[i]表示節點i的next指針是多少 //e[i]表示節點i 的值 //head 表示頭結點的下標 //idx 存儲當前已經用了哪個點 void init() {head -1;//頭結點指向下標為…

前端實現PDF文件打印和下載

在Web開發中&#xff0c;經常需要處理PDF文件&#xff0c;尤其是在業務涉及發票、報告或文檔生成的場景下。本文將詳細介紹如何使用前端技術實現PDF文件的打印和下載&#xff0c;我們將利用HTML5的<embed>元素和JavaScript庫FileSaver.js來完成這一任務。 一、環境準備 …

Python 爬蟲:使用打碼平臺來識別各種驗證碼:

本課程使用的是 超級鷹 打碼平臺&#xff0c; 沒有賬戶的請自行注冊&#xff01; 超級鷹驗證碼識別-專業的驗證碼云端識別服務,讓驗證碼識別更快速、更準確、更強大 使用打碼平臺來攻破驗證碼難題&#xff0c; 是很簡單容易的&#xff0c; 但是要錢&#xff01; 案例代碼及測…

React18+Redux+antd 項目實戰 JS

React18Reduxantd 項目實戰 js Ant Design插件官網 Axios官網 (可配置請求攔截器和響應攔截器) JavaScript官網 Echarts官網 一、項目前期準備 1.創建新項目 hotel-manager npx create-react-app hotel-manager2.安裝依賴 //安裝路由 npm i react-router-domnpm i aixos /…

CentOS搭建郵件服務器:DNS配置方法技巧?

CentOS搭建郵件服務器的流程&#xff1f;如何高效使用CentOS&#xff1f; 在當今數字化時代&#xff0c;郵件服務器的需求日益增加。為了確保郵件能夠順利送達&#xff0c;正確的DNS配置是必不可少的一環。AokSend將詳細介紹在CentOS搭建郵件服務器過程中&#xff0c;如何進行…

SpringBoot新手快速入門系列教程7:基于Redis的一個簡單存取數據的例子

我的教程都是親自測試可行才發布的&#xff0c;如果有任何問題歡迎留言或者來群里我每天都會解答。 新手可能有這樣的疑問&#xff0c;有了數據庫的存取方式&#xff0c;我們為什么還要使用Redis這種緩存數據庫讀取方式呢&#xff1f; 原因主要有以下幾點&#xff1a; 1. 性能…

力扣題解(單詞拆分)

139. 單詞拆分單詞拆分 給你一個字符串 s 和一個字符串列表 wordDict 作為字典。如果可以利用字典中出現的一個或多個單詞拼接出 s 則返回 true。 注意&#xff1a;不要求字典中出現的單詞全部都使用&#xff0c;并且字典中的單詞可以重復使用。 思路&#xff1a; 規定dp[i]…

亞馬遜中小型店鋪如何開店?

對于想要在亞馬遜平臺上開設店鋪的中小型賣家來說&#xff0c;這是一個非常值得關注的話題。作為亞馬遜上的一個重要參與者&#xff0c;中小型店鋪有著廣闊的發展空間和無限的可能性&#xff0c;但也由于成本預算與規模限制&#xff0c;無法與大型店鋪的策略相提并論&#xff0…

字符串模板被噶了,JDK 23 刪除了預覽功能“字符串模板”

之前出了一個視頻&#xff0c;介紹 JDK 23 中的新特性。之后我才發現&#xff0c;在 JDK 21 和 22 中的預覽功能“字符串模板&#xff08;String Templates&#xff09;”&#xff0c;在 JDK 23 中已經沒有了。字符串模板的相關代碼&#xff0c;已經被全部刪除了。 字符串模板的…

Spring Boot 3.3 【二】Spring Boot自動配置機制深度解析

簡單動作&#xff0c;深刻聯結。在這技術海洋&#xff0c;我備好舟&#xff0c;等你揚帆。啟航吧&#xff01; &#x1f31f;點擊【關注】&#xff0c;解鎖定期的技術驚喜&#xff0c;讓靈感與知識的源泉不斷涌動。 &#x1f44d;一個【點贊】&#xff0c;如同心照不宣的默契&a…

Unity免費領場景多人實時協作地編2人版局域網和LAN聯機類似谷歌文檔協同合作搭建場景同步資產設置編輯付費版支持10人甚至更多20240709

大家有沒有用過谷歌文檔、石墨文檔、飛書文檔等等之類的協同工具呢&#xff1f; Blender也有類似多人聯機建模的插件&#xff0c; Unity也有類似的多人合作搭建場景的插件啦。 剛找到一款免費插件&#xff0c;可以支持2人局域網和LAN聯機地編。 付費的版本支持組建更大的團隊。…

詳解如何通過稀疏向量優化信息檢索

在信息檢索方法的發展歷程中&#xff0c;我們見證了從傳統的統計關鍵詞匹配到如 BERT 這樣的深度學習模型的轉變。雖然傳統方法提供了堅實的基礎&#xff0c;但往往難以精準捕捉文本的語義關系。如 BERT 這樣的稠密檢索方法通過利用高維向量捕獲文本的上下文語義&#xff0c;為…

煙霧識別技術在火災預防中的應用:思通數科大模型的力量

引言 火災是導致生命財產損失的重大災害之一。早期檢測和快速響應是預防火災和減少損失的關鍵。結合思通數科大模型的煙霧識別技術&#xff0c;為實時檢測和精確定位煙霧來源提供了一種高效的解決方案。本文將探討這一技術如何有效預防火災并保障人員安全。 煙霧識別技術概述 …

注冊自定義總線

1、在/sys/bus下注冊一個自定義總線 #include<linux/module.h> #include<linux/init.h> #include<linux/kernel.h> #include<linux/kobject.h> #include<linux/slab.h> #include<linux/sysfs.h> #include<linux/device.h> #include…

bug修復 修復修復修復

好的&#xff0c;這里是更新后的代碼&#xff0c;將所有 inRange 函數的第一個變量替換為 ZoomOutimage&#xff1a; // 綠色分岔路 if (divergerColor "green" && nextColor "null") {cv::Mat frameGreen, frameRed;frame2.copyTo(frameGreen)…

如何在 Fedora 中使用 `shred` 擦除驅動器或文件

English Version: https://blog.csdn.net/sch0120/article/details/140390161 如何在 Fedora 中使用 shred 擦除驅動器或文件 安全擦除驅動器對于保護您的敏感數據免受未授權訪問至關重要。在這篇博文中&#xff0c;我們將學習如何在 Fedora 中使用 shred 命令安全擦除整個驅…

FATE Flow 源碼解析 - 作業提交處理流程

背景介紹 FATE 是隱私計算中最有名的開源項目了&#xff0c;從 star 的數量上來看也可以看出來。截止 2023 年 3 月共收獲 4.9k 個 star&#xff0c;但是 FATE 一直被認為代碼框架復雜&#xff0c;難以理解&#xff0c;作為一個相關的從業者&#xff0c;后續會持續對 FATE 項目…

React@16.x(56)Redux@4.x(5)- 實現 createStore

目錄 1&#xff0c;分析2&#xff0c;實現2.1&#xff0c;基礎實現2.2&#xff0c;優化2.2.1&#xff0c;隨機字符串2.2.2&#xff0c;action 的判斷2.2.2&#xff0c;監聽器的優化 2.3&#xff0c;最終形態 1&#xff0c;分析 createStore()&#xff0c;參數1為 reducer&…

0601STM32TIM

TOC 分為四部分&#xff0c;八小節 一部分&#xff1a;主要講定時器基本定時的功能&#xff0c;也就是定一個事件&#xff0c;讓定時器每隔這個時間產生一個中斷&#xff0c;來實現每隔一個固定時間來執行一段程序的目的&#xff0c;比如做一個時鐘、秒表&#xff0c;或者使用一…

【Linux】1w詳解如何實現一個簡單的shell

目錄 實現思路 1. 交互 獲取命令行 2. 子串分割 解析命令行 3. 指令的判斷 內建命令 4. 普通命令的執行 補充&#xff1a;vim 文本替換 整體代碼 重點思考 1.getenv和putenv是什么意思 2.代碼extern char **environ; 3.內建命令是什么 4.lastcode WEXITSTATUS(sta…