最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++?關(guān)聯(lián)式容器map?與?set?的原理與實踐操作

 更新時間:2025年12月01日 09:29:40   作者:思成不止于此  
本文將詳細(xì)介紹關(guān)聯(lián)式容器中最常用的map和set,包括它們的底層實現(xiàn)、核心特性、使用方法及實際應(yīng)用,本文結(jié)合實例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧

        在 C++ 中,容器是存放數(shù)據(jù)的重要數(shù)據(jù)結(jié)構(gòu),分為序列式容器和關(guān)聯(lián)式容器。序列式容器(如 vector、list、deque)按線性順序存儲元素,元素的位置與值無關(guān);而關(guān)聯(lián)式容器則通過鍵(key)建立元素間的關(guān)聯(lián),實現(xiàn)高效的查找、插入和刪除操作。本文將詳細(xì)介紹關(guān)聯(lián)式容器中最常用的 map 和 set,包括它們的底層實現(xiàn)、核心特性、使用方法及實際應(yīng)用。

一、關(guān)聯(lián)式容器的核心概念

1. 容器分類與特點

        關(guān)聯(lián)式容器的核心是 “關(guān)聯(lián)關(guān)系”,即通過鍵(key)快速定位元素,而無需像序列式容器那樣遍歷整個容器。其特點如下:

  • 元素按特定規(guī)則排序(有序容器)或無序存儲(無序容器);
  • 插入位置由元素的鍵決定,而非用戶指定;
  • 查找效率極高,平均時間復(fù)雜度為 O(logN)(有序容器)或 O(1)(無序容器)。

2. 底層實現(xiàn)

        有序容器(set、map 等)的底層通常采用 平衡二叉搜索樹(紅黑樹) 實現(xiàn),其特性為:

  • 左子樹所有節(jié)點的值 < 根節(jié)點的值;
  • 右子樹所有節(jié)點的值 > 根節(jié)點的值;
  • 樹的高度保持平衡,確保查找、插入、刪除操作的時間復(fù)雜度為 O(logN)。

        無序容器(unordered_set、unordered_map 等)的底層采用 哈希表 實現(xiàn),通過哈希函數(shù)將鍵映射到存儲位置,平均時間復(fù)雜度為 O(1),但最壞情況下可能退化為 O(N)。

3. 搜索模型

        關(guān)聯(lián)式容器分為兩種搜索模型:

  • K 模型:僅存儲鍵(key),如 set,核心功能是判斷元素是否存在;
  • KV 模型:存儲鍵值對(key-value),如 map,核心功能是通過鍵查找對應(yīng)的值。

二、set 的原理與使用

1. set 的核心特性

        set 是 有序、不重復(fù) 的 K 模型容器,底層為紅黑樹。其核心特性:

  • 自動排序:插入元素后,容器會按鍵的升序(默認(rèn))排列;
  • 自動去重:插入重復(fù)元素時,操作會失敗,容器中僅保留一個實例;
  • 不可修改元素:set 中的元素是 const 類型,修改元素會破壞紅黑樹的結(jié)構(gòu),需通過 “刪除舊元素 + 插入新元素” 實現(xiàn)。

2. set 的常用操作

(1)插入操作

        set 不支持 push_back/push_front,需使用 insert() 插入元素:

#include <set>
using namespace std;
set<int> s;
s.insert(3);   
s.insert(1);   
s.insert(3);   // 重復(fù)插入,操作失敗

        插入后,set 中的元素會自動排序為 {1, 3}

(2)遍歷操作

set 支持迭代器遍歷和范圍 for 遍歷:

void test(){
    set<int> s;
    s.insert(3);
    s.insert(4);
    s.insert(1);
    s.insert(2);
    s.insert(3);
    s.insert(7);
    //排序+去重
    set<int>::iterator it = s.begin();
    while (it != s.end())
    {
	    cout << *it << " ";
	    it++;
    }
    cout << endl;
    for (auto e : s)
    {
    	cout << e << " ";
    }
    cout << endl;
}

(3)刪除操作

        set 支持兩種刪除方式:

  • 通過迭代器刪除(需先通過 find() 查找元素);
  • 直接通過值刪除。
// 方式 1:通過迭代器刪除
set<int>::iterator pos = s.find(7);	//log(N)
//set<int>::iterator pos = find(s.begin(), s.end(), 4); //OP(N)
if (pos != s.end())
{
	s.erase(pos);
}
// 方式 2:直接通過值刪除
s.erase(1);  // 刪除元素 1,若不存在則無操作

(4)查找操作

        set 的查找功能是其核心,提供兩種方式:

  • 成員函數(shù) find():利用紅黑樹特性,時間復(fù)雜度 O(logN);
  • 算法 std::find():線性遍歷,時間復(fù)雜度 O(N)。

示例對比

#include <algorithm>  // 包含 std::find
// 成員函數(shù) find()
set<int>::iterator pos1 = s.find(3);  // 高效查找
// 算法 find()
set<int>::iterator pos2 = find(s.begin(), s.end(), 3);  // 低效遍歷

使用建議:優(yōu)先使用 set 的成員函數(shù) find() 以獲得最佳性能。

3. set 的實際應(yīng)用

        set 的核心優(yōu)勢是 快速存在性檢查 和 高效去重排序,適用于以下場景:

  • 存儲學(xué)號、身份證號等唯一標(biāo)識,快速驗證是否存在;
  • 對輸入數(shù)據(jù)去重并排序,如統(tǒng)計考試成績的不重復(fù)分?jǐn)?shù);
  • 實現(xiàn)集合運(yùn)算(交集、并集、差集)。

示例:驗證學(xué)號是否存在

student_ids.insert("001");
student_ids.insert("002");
student_ids.insert("003");
string id = "002";
if (student_ids.find(id) != student_ids.end()) {
    cout << "學(xué)號 " << id << " 存在" << endl;
} else {
    cout << "學(xué)號 " << id << " 不存在" << endl;
}

三、map 的原理與使用

1. map 的核心特性

        map 是 有序、鍵唯一 的 KV 模型容器,底層為紅黑樹。其核心特性:

  • 存儲鍵值對(key-value),鍵(key)唯一,值(value)可重復(fù);
  • 按鍵自動排序(默認(rèn)升序);
  • 通過鍵快速查找對應(yīng)的值,時間復(fù)雜度 O(logN);
  • 支持通過鍵修改值,但鍵不可修改(否則會破壞紅黑樹結(jié)構(gòu))。

2. map 的常用操作

(1)pair 類型介紹

        map 中的元素是 pair<const key_type, value_type> 類型,pair 是一個模板結(jié)構(gòu)體,包含兩個成員:

  • first:鍵(key),不可修改;
  • second:值(value),可修改。

創(chuàng)建 pair 的方式:

// 方式 1:顯式指定模板參數(shù)
pair<int, string> p1(1, "張三");
// 方式 2:使用 make_pair(自動推導(dǎo)類型)
pair<int, string> p2 = make_pair(2, "李四");

(2)插入操作

        map 通過 insert() 插入 pair 類型元素:

#include <map>
using namespace std;
map<int, string> student_info;
// 方式 1:插入 pair 對象
student_info.insert(pair<int, string>(1, "張三"));
// 方式 2:使用 make_pair(推薦,更簡潔)
student_info.insert(make_pair(2, "李四"));
// 方式 3:C++11 統(tǒng)一初始化
student_info.insert({3, "王五"});

        插入后,map 會按鍵的升序排列:{1:張三, 2:李四, 3:王五}。

(3)遍歷操作

        map 支持迭代器遍歷和范圍 for 遍歷,通過 it->first 訪問鍵,it->second 訪問值:

// 迭代器遍歷
map<int, string>::iterator it = student_info.begin();
while (it != student_info.end()) {
    cout << "學(xué)號:" << it->first << ",姓名:" << it->second << endl;
    ++it;
}
// 范圍 for 遍歷
for (auto e : student_info) {
    cout << "學(xué)號:" << e.first << ",姓名:" << e.second << endl;
}

(4)查找與修改操作

        通過鍵查找值有兩種方式:

  • 成員函數(shù) find():返回指向該鍵值對的迭代器;
  • 下標(biāo)運(yùn)算符 []:直接通過鍵訪問值(若鍵不存在,會自動插入一個默認(rèn)構(gòu)造的鍵值對)。
// 方式 1:find() 查找(推薦,避免誤插入)
map<int, string>::iterator pos = student_info.find(2);
if (pos != student_info.end()) {
    cout << "找到:" << pos->second << endl;  // 輸出:李四
    pos->second = "李小四";  // 修改值
}
// 方式 2:下標(biāo)訪問(注意:鍵不存在時會自動插入)
string name = student_info[3];  // 訪問鍵 3 的值,存在則返回 "王五"
student_info[4] = "趙六";       // 鍵 4 不存在,插入 {4:趙六}

(5)刪除操作

        map 的刪除方式與 set 類似,支持迭代器刪除和鍵刪除:

// 方式 1:通過迭代器刪除
map<int, string>::iterator pos = student_info.find(2);
if (pos != student_info.end()) {
    student_info.erase(pos);
}
// 方式 2:通過鍵刪除
student_info.erase(3);  // 刪除鍵 3 對應(yīng)的鍵值對

3. map 的實際應(yīng)用

        map 的核心優(yōu)勢是 通過鍵快速查找值,適用于以下場景:

  • 存儲鍵值對映射關(guān)系,如字典(單詞 - 翻譯)、學(xué)號 - 成績;
  • 統(tǒng)計元素出現(xiàn)次數(shù),如統(tǒng)計字符串中每個單詞的出現(xiàn)次數(shù);
  • 實現(xiàn)緩存機(jī)制(鍵為緩存 key,值為緩存數(shù)據(jù))。

示例:統(tǒng)計字符串出現(xiàn)次數(shù)

string str[] = { "西瓜","圣女果", "圣女果", "西瓜", "西瓜", "香蕉", "葡萄", "葡萄", "菠蘿", "西瓜", "桃子", "西瓜",  "栗子", "水蜜桃", "西瓜", "葡萄" };
map<string, int> countMap;
for (auto e : str)
{
	map<string, int>::iterator pos = countMap.find(e);
	if (pos == countMap.end())
		countMap.insert(make_pair(e, 1));
	else
		pos->second++;	
}
for (auto e : countMap)
{
	cout << e.first<<":"<<e.second<<endl;
}

四、map 與 set 的區(qū)別與聯(lián)系

1. 相同點

  • 底層均為紅黑樹(有序容器),操作時間復(fù)雜度均為 O(logN);
  • 均支持自動排序和去重(set 去重鍵,map 去重鍵);
  • 均不支持直接修改元素(set 元素不可修改,map 鍵不可修改)。

2. 不同點

特性setmap
存儲類型僅鍵(K 模型)鍵值對(KV 模型)
核心功能快速存在性檢查快速鍵值映射查找
元素訪問僅訪問鍵訪問鍵和值
修改方式不可修改,需刪插可修改值,鍵不可改

五、使用注意事項

  1. 元素不可修改:set 的元素和 map 的鍵均為 const 類型,修改會破壞紅黑樹結(jié)構(gòu),需通過 “刪插” 實現(xiàn);
  2. 迭代器有效性:插入元素時,紅黑樹可能重新平衡,迭代器不會失效;刪除元素時,僅被刪除元素的迭代器失效,其他迭代器有效;
  3. 比較規(guī)則:默認(rèn)按鍵的升序排序,若需自定義排序,可在定義容器時指定比較函數(shù)(如 set<int, greater<int>> 按降序排序);
  4. 效率選擇
    • 需有序存儲且高效查找時,使用 set/map;
    • 無需排序且追求極致查找效率時,使用 unordered_set/unordered_map(哈希表實現(xiàn));
    • 僅需線性存儲時,使用 vector/list 等序列式容器。

六、總結(jié)

        map 和 set 是 C++ 中最常用的關(guān)聯(lián)式容器,其核心優(yōu)勢在于 高效的查找、插入和刪除操作,底層依賴紅黑樹實現(xiàn)有序存儲和去重。set 專注于 “鍵的存在性檢查”,map 專注于 “鍵值對的映射查找”,二者在實際開發(fā)中應(yīng)用廣泛,如數(shù)據(jù)去重、統(tǒng)計計數(shù)、字典映射等場景。

        掌握 map 和 set 的使用,需理解其底層實現(xiàn)原理和核心特性,根據(jù)實際需求選擇合適的容器,以優(yōu)化程序性能。

到此這篇關(guān)于C++ 關(guān)聯(lián)式容器map 與 set 的原理與實踐操作的文章就介紹到這了,更多相關(guān)c++ map和set原理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • c語言中的移位運(yùn)算符

    c語言中的移位運(yùn)算符

    這篇文章主要介紹了c語言中的移位運(yùn)算符,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • 詳談c++11 final與override說明符

    詳談c++11 final與override說明符

    下面小編就為大家?guī)硪黄斦刢++11 final與override說明符。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-01-01
  • C語言實現(xiàn)學(xué)生管理系統(tǒng)總結(jié)

    C語言實現(xiàn)學(xué)生管理系統(tǒng)總結(jié)

    這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)學(xué)生管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • Qt中QSettings配置文件的讀寫和應(yīng)用場景詳解

    Qt中QSettings配置文件的讀寫和應(yīng)用場景詳解

    這篇文章主要給大家介紹了關(guān)于Qt中QSettings配置文件的讀寫和應(yīng)用場景的相關(guān)資料,QSettings能讀寫配置文件,當(dāng)配置文件不存在時,可生成配置文件,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-10-10
  • c++顯式棧實現(xiàn)遞歸介紹

    c++顯式棧實現(xiàn)遞歸介紹

    大家好,本篇文章主要講的是c++顯式棧實現(xiàn)遞歸介紹,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • C++變量多維分類的具體使用

    C++變量多維分類的具體使用

    C++變量可從作用域/生命周期、存儲類型、數(shù)據(jù)類型三個維度分類,本文就來詳細(xì)的介紹一下C++變量的多維分類的具體使用,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-09-09
  • 解決Visual?Studio?Code錯誤Cannot?build?and?debug?because?the

    解決Visual?Studio?Code錯誤Cannot?build?and?debug?because?

    這篇文章主要為大家介紹了解決Visual?Studio?Code錯誤Cannot?build?and?debug?because?the及分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • C語言獲取Linux系統(tǒng)精確時間的方法

    C語言獲取Linux系統(tǒng)精確時間的方法

    下面小編就為大家?guī)硪黄狢語言獲取Linux系統(tǒng)精確時間的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • C語言:十進(jìn)制,BCD碼互換詳解

    C語言:十進(jìn)制,BCD碼互換詳解

    這篇文章主要介紹了C語言十進(jìn)制,BCD碼互換實例,小編覺得這篇文章寫的還不錯,實例簡單明了,需要的朋友可以參考下
    2021-09-09
  • C語言sizeof和strlen的指針和數(shù)組面試題詳解

    C語言sizeof和strlen的指針和數(shù)組面試題詳解

    strlen是函數(shù),字符串長度,不包括停止符。而sizeof則是內(nèi)存塊的大小,包括停止符。數(shù)組是一種數(shù)據(jù)類型,數(shù)據(jù)類型的本質(zhì)就是固定大小,內(nèi)存塊的別名??梢杂胹izeof()一般都是數(shù)據(jù)類型
    2022-04-04

最新評論

静宁县| 剑川县| 财经| 北票市| 峡江县| 天长市| 开封市| 海丰县| 汝南县| 宜兰市| 德惠市| 资兴市| 大悟县| 临西县| 安宁市| 牟定县| 丰镇市| 云南省| 永年县| 晴隆县| 周宁县| 葫芦岛市| 潞西市| 无为县| 湘潭县| 尼勒克县| 花莲县| 平度市| 确山县| 沂源县| 泉州市| 宁津县| 安塞县| 宜丰县| 九江县| 巨野县| 临海市| 贺兰县| 教育| 囊谦县| 额济纳旗|