自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

C++ STL之std::map:紅黑樹(shù)的魔法與性能測(cè)試

開(kāi)發(fā) 前端
本文將深入探討std::map以及其核心紅黑樹(shù)的原理,解釋其關(guān)鍵特性,包括插入、查找和刪除操作,以及有序性的優(yōu)勢(shì)。

最近在使用C++寫(xiě)代碼,也是剛接觸C++,恰巧碰到一個(gè)需要使用map的地方,不知道其查找元素的性能怎么樣,所以研究了下,做個(gè)記錄,目前從x86平臺(tái)測(cè)試map查找一個(gè)元素大概需要2us,這里你需要考慮在自身硬件平臺(tái)比如arm,做一些cpu加壓情況下再查看map效率以評(píng)估m(xù)ap是否滿足業(yè)務(wù)需求。

在C++編程的世界中,STL(標(biāo)準(zhǔn)模板庫(kù))一直以其強(qiáng)大的數(shù)據(jù)結(jié)構(gòu)和算法而著稱。其中,std::map是STL提供的一個(gè)關(guān)聯(lián)容器,它的核心是紅黑樹(shù)(Red-Black Tree)數(shù)據(jù)結(jié)構(gòu)。紅黑樹(shù)是一種自平衡的二叉查找樹(shù),以其出色的性能和平衡機(jī)制而備受推崇。

本文將深入探討std::map以及其核心紅黑樹(shù)的原理,解釋其關(guān)鍵特性,包括插入、查找和刪除操作,以及有序性的優(yōu)勢(shì)。我們還將進(jìn)行性能測(cè)試,以展示std::map在實(shí)際應(yīng)用中的卓越性能。

一、紅黑樹(shù),std::map的核心

std::map的核心數(shù)據(jù)結(jié)構(gòu)是紅黑樹(shù)(Red-Black Tree)數(shù)據(jù)結(jié)構(gòu)。紅黑樹(shù)是一種自平衡二叉查找樹(shù),它具有以下特性:

  • 每個(gè)節(jié)點(diǎn)是紅色或黑色:每個(gè)節(jié)點(diǎn)都被標(biāo)記為紅色或黑色,這是紅黑樹(shù)的基本性質(zhì)之一。
  • 根節(jié)點(diǎn)是黑色:樹(shù)的根節(jié)點(diǎn)始終是黑色的。
  • 每個(gè)葉子節(jié)點(diǎn)(NIL節(jié)點(diǎn),通常表示為黑色)都被認(rèn)為是黑色的:NIL節(jié)點(diǎn)是樹(shù)的末端節(jié)點(diǎn),它們通常被表示為黑色。
  • 如果一個(gè)節(jié)點(diǎn)是紅色的,那么它的子節(jié)點(diǎn)必須是黑色的:這一性質(zhì)確保沒(méi)有兩個(gè)相鄰的紅色節(jié)點(diǎn)。
  • 從任何給定節(jié)點(diǎn)到其后代葉子節(jié)點(diǎn)的每條路徑都包含相同數(shù)量的黑色節(jié)點(diǎn):這個(gè)性質(zhì)保證了樹(shù)的平衡。

這些性質(zhì)保證了紅黑樹(shù)的平衡性,使得樹(shù)的高度保持相對(duì)較小,從而提供了高效的查找、插入和刪除操作。

二、std::map常見(jiàn)操作

1.插入操作:保持平衡

當(dāng)您向std::map插入新的鍵值對(duì)時(shí),紅黑樹(shù)需要進(jìn)行一系列旋轉(zhuǎn)和著色操作,以保持樹(shù)的平衡。這確保了即使在大規(guī)模數(shù)據(jù)集下,插入操作仍然高效。

// 插入操作示例
std::map<int, std::string> myMap;
myMap[42] = "Hello, World!";

在插入操作中,紅黑樹(shù)遵循一些規(guī)則,例如:

  • 新插入的節(jié)點(diǎn)通常是紅色的。
  • 如果插入破壞了紅黑樹(shù)的性質(zhì),就需要執(zhí)行旋轉(zhuǎn)和著色操作來(lái)恢復(fù)平衡。

2.查找操作:速度與效率

std::map的查找操作非常高效,因?yàn)榧t黑樹(shù)的結(jié)構(gòu)使得它可以迅速定位到所需的節(jié)點(diǎn)。查找操作會(huì)從根節(jié)點(diǎn)開(kāi)始,根據(jù)鍵值比較逐步沿樹(shù)向下移動(dòng),直到找到目標(biāo)節(jié)點(diǎn)或確定目標(biāo)節(jié)點(diǎn)不在樹(shù)中。這個(gè)過(guò)程的時(shí)間復(fù)雜度是O(log N),其中N是樹(shù)中元素的數(shù)量。

// 查找操作示例
auto result = myMap.find(42);
if (result != myMap.end()) {
    std::cout << "Found: " << result->second << std::endl;
} else {
    std::cout << "Not found!" << std.endl;
}

3.刪除操作:平衡的維護(hù)

刪除操作也是相對(duì)復(fù)雜的,因?yàn)樗枰3謽?shù)的平衡。當(dāng)刪除一個(gè)節(jié)點(diǎn)時(shí),可能會(huì)引起樹(shù)的不平衡,需要執(zhí)行旋轉(zhuǎn)和著色操作來(lái)修復(fù)它。這些操作確保了紅黑樹(shù)的性質(zhì)仍然得以維持。

// 刪除操作示例
myMap.erase(42);

在刪除操作中,紅黑樹(shù)也遵循一系列規(guī)則,包括:

  • 如果刪除的節(jié)點(diǎn)是紅色的,可能不會(huì)破壞樹(shù)的性質(zhì)。
  • 如果刪除的節(jié)點(diǎn)是黑色的,就可能會(huì)引發(fā)平衡問(wèn)題,需要執(zhí)行一系列的操作來(lái)修復(fù)。

4.有序性:按鍵排序

std::map中的元素是按鍵值有序排列的,這意味著您可以使用迭代器來(lái)遍歷元素,或者進(jìn)行范圍查找。

// 使用迭代器遍歷示例
for (const auto& pair : myMap) {
    std::cout << "Key: " << pair.first << ", Value: " << pair.second << std::endl;
}

三、性能測(cè)試:查找操作

下面是一個(gè)性能測(cè)試示例,因?yàn)槲覍?duì)查找某個(gè)元素的性能是有要求的,所以做了一個(gè)簡(jiǎn)單測(cè)試:

#include <iostream>
#include <map>
#include <random>
#include <chrono>

int main() {
    std::map<int, int> testMap;
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution<int> dist(1, 1000000);

    // 插入100,000個(gè)隨機(jī)鍵值對(duì)
    for (int i = 0; i < 100000; ++i) {
        int key = dist(gen);
        int value = i;
        testMap[key] = value;
    }

    // 測(cè)試查找操作的效率
    int totalIterations = 100000;
    int foundCount = 0;
    std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now();

    for (int i = 0; i < totalIterations; ++i) {
        int key = dist(gen);
        if (testMap.find(key) != testMap.end()) {
            foundCount++;
        }
    }

    std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> duration = std::chrono::duration_cast<std::chrono::duration<double>>(end - start);

    std::cout << "查找 " << totalIterations << " 個(gè)元素所用時(shí)間: " << duration.count() << " 秒" << std::endl;
    std::cout << "找到 " << foundCount << " 個(gè)元素" << std::endl;
    std::cout << "查找單個(gè)元素耗時(shí): " << (duration.count()*1000000) / totalIterations << " 微秒" << std::endl;

    return 0;
}

我們首先插入了100,000個(gè)隨機(jī)鍵值對(duì),然后執(zhí)行查找操作,并記錄查找到的元素?cái)?shù)量,并計(jì)算時(shí)間。

使用g++編譯執(zhí)行結(jié)果:

四、總結(jié)

std::map是C++編程中的神奇工具,它提供高效的查找、插入和刪除操作,并按鍵排序數(shù)據(jù)。紅黑樹(shù)的自平衡性確保了它在各種操作下都能保持高效性。無(wú)論是實(shí)現(xiàn)關(guān)鍵功能還是性能測(cè)試,std::map都展現(xiàn)了其出色之處,使其成為處理大規(guī)模數(shù)據(jù)集的理想之選。

責(zé)任編輯:趙寧寧 來(lái)源: 囧囧妹
相關(guān)推薦

2020-09-17 07:37:09

紅黑樹(shù)數(shù)據(jù)結(jié)構(gòu)

2020-07-09 07:00:00

HashMap

2009-12-11 10:02:46

Linux內(nèi)存管理

2023-03-31 08:24:29

數(shù)據(jù)結(jié)構(gòu)算法數(shù)目

2010-07-13 09:10:26

.NETMonoJava

2019-10-12 08:36:48

Java程序員數(shù)據(jù)結(jié)構(gòu)

2016-12-08 11:01:39

紅黑樹(shù)Java

2023-11-24 16:13:05

C++編程

2020-11-05 13:12:47

紅黑樹(shù)

2020-11-05 09:03:32

紅黑樹(shù)面試數(shù)據(jù)

2020-10-09 06:56:55

紅黑樹(shù)動(dòng)圖二叉樹(shù)

2011-07-20 13:57:06

C++STL

2024-01-24 12:30:18

C++開(kāi)發(fā)庫(kù)

2015-04-29 15:29:16

C++ STL內(nèi)存配置關(guān)鍵源碼分析

2019-08-22 09:22:44

數(shù)據(jù)結(jié)構(gòu)二叉搜索樹(shù)

2020-03-11 08:40:51

紅黑樹(shù)平衡二叉B樹(shù)

2023-10-04 00:38:30

C++原子

2011-07-20 14:12:48

2011-07-20 13:57:06

C++STL

2020-05-06 16:41:36

紅黑樹(shù)二叉查找樹(shù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)