進階數據結構:用紅黑樹實現封裝map和set

?

嘿,各位技術潮人!好久不見甚是想念。生活就像一場奇妙冒險,而編程就是那把超酷的萬能鑰匙。此刻,陽光灑在鍵盤上,靈感在指尖跳躍,讓我們拋開一切束縛,給平淡日子加點料,注入滿滿的
passion。準備好和我一起沖進代碼的奇幻宇宙了嗎?Let’s go!

請添加圖片描述

我的博客:yuanManGan

我的專欄:C++入門小館 C言雅韻集 數據結構漫游記 閑言碎語小記坊
進階數據結構 走進Linux的世界 題山采玉 領略算法真諦

在這里插入圖片描述


用紅黑樹實現封裝map和set


實現步驟:

  1. 實現紅黑樹
  2. 封裝 mapset 框架解決KeyOfT
  3. iterator
  4. const_iterator
  5. key不支持修改的問題
  6. operator[ ]

1.實現紅黑樹

上集我們已經實現了一個普通的紅黑樹 進階數據結構:紅黑樹,


2.封裝 map 和 set 框架解決KeyOfT


查看stl源碼借鑒了解

發現實現 setmap 都包含了一個 tree 頭文件,我們那篇博客實現的 key-value 的紅黑樹,那我們是不是要實現兩個紅黑樹一個是 key 的一個 key-value 的呢?
stl中實現set和map所包含的頭文件


不急我們看看源碼:

template<typename _Key, typename _Val, typename _KeyOfValue,typename _Compare, typename _Alloc = allocator<_Val> >class _Rb_tree{}

我們湊湊這模板,這怎么又有key又有value那它怎么實現的set , set 不是不要value嗎?


我來解釋一下吧:

  • 可能寫這個代碼的程序員寫的不太規范,這個地方的Val代表的不是我們之前寫代碼的value
  • 而是比如我們set傳入的keymap傳入的key_value,代表的是這一類,而不是單純的value
  • 我們就這樣形成了模板,本質上編譯器還是寫了兩份代碼,但增加了復用,減少了我們自己寫。

那又有人問了,那我們不是只要一個模板參數就夠了嗎,為什么前面還得加個key呢?

  • 我們實現 find 等功能的時候需要使用到 key,所以不能偷懶

更改我們的紅黑樹

我們寫就寫的規范一點,我們將 V 替換為 T

//原本
////////////////////////////////////////////////////////////////
template <class K,class V>
struct RBTreeNode
{pair<K, V> _kv;RBTreeNode<K, V>* _parent;RBTreeNode<K, V>* _left;RBTreeNode<K, V>* _right;Colour _col;RBTreeNode(const pair<K, V>& kv): _kv(kv), _parent(nullptr), _left(nullptr), _right(nullptr)  // 按聲明順序放在_col之前, _col(RED){}
};
template <class K, class V>
class RBTree
{typedef RBTreeNode<K, V> Node;
public://...
private:Node* _root = nullptr;
};
////////////////////////////////////////////////////////////////
//修改后
template <class T>
struct RBTreeNode
{T _data;RBTreeNode<T>* _parent;RBTreeNode<V>* _left;RBTreeNode<V>* _right;Colour _col;RBTreeNode(T& data): _data(data), _parent(nullptr), _left(nullptr), _right(nullptr)  // 按聲明順序放在_col之前, _col(RED){}
};
template <class K, class T>
class RBTree
{typedef RBTreeNode<K, T> Node;
public://...
private:Node* _root = nullptr;
};

我們在修改 Insert 這個函數的時候就遇到的問題,我們怎么比較插入節點與原節點的大小呢?

  • 我們可以引入一個模板參數 KeyOfT 分別在 setmap頭文件里面重載 ( ) 實現比較邏輯,如果是set就直接返回 keymap就返回kv中的 first

//set.h
template<class K>
class set
{struct SetKeyOfT{const K& operator()(const K& key){return key;}};
public://...
private:RBTree<K, K, SetKeyOfT> _t;	
};
//map.h
template<class K, class V>
class map
{struct MapKeyOfT{const K& operator()(const pair<K, V>& kv){return kv.first;}};
public://...
private:RBTree<K, pair<K, V>, MapKeyOfT> _t;	
};
  • insert
KeyOfT kot;
bool Insert(const T& data)
{//插入//空樹if (_root == nullptr){_root = new Node(data);_root->_col = BLACK;return true;}Node* cur = _root;Node* parent = nullptr;while (cur){if (kot(data) > kot(cur->_data)){parent = cur;cur = cur->_right;}else if (kot(data) < kot(cur->_data)){parent = cur;cur = cur->_left;}else {return false;}}cur = new Node(data);cur->_col = RED;if (kot(data) > kot(parent->_data)){//是p的右子樹parent->_right = cur;}else{//是p的左子樹parent->_left = cur;}cur->_parent = parent;//變色while (parent && parent->_col == RED){Node* grandfather = parent->_parent;if (grandfather->_left == parent){Node* uncle = grandfather->_right;//u存在且為紅if (uncle && uncle->_col == RED){//變色parent->_col = uncle->_col = BLACK;grandfather->_col = RED;//繼續往上處理cur = grandfather;parent = cur->_parent;}else{//u存在但為黑if (cur == parent->_left){//c在左//     g           p  //   p   u --->  c   g// c                   uRotateR(grandfather);grandfather->_col = RED;parent->_col = BLACK;}else{//c在右//     g    RotateL(p)        g    RotateR(g)    c//  p     u ----------->   c     u -------->  p     g//     c                 p                             u      RotateL(parent);RotateR(grandfather);cur->_col = BLACK;grandfather->_col = RED;}break;}}else{Node* uncle = grandfather->_left;//u存在且為紅if (uncle && uncle->_col == RED){//變色parent->_col = uncle->_col = BLACK;grandfather->_col = RED;//繼續往上處理cur = grandfather;parent = cur->_parent;}else{//u存在但為黑if (cur == parent->_right){//c在右//     g           p  //   u   p --->  g   c//         c   uRotateL(grandfather);grandfather->_col = RED;parent->_col = BLACK;}else{//c在z左//     g    RotateR(p)      g    RotateL(g)    c//  u     p -----------> u     c -------->  g     p//     c                        p        u      RotateR(parent);RotateL

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

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

相關文章

【數據結構初階】--二叉樹(五)

&#x1f525;個人主頁&#xff1a;草莓熊Lotso &#x1f3ac;作者簡介&#xff1a;C研發方向學習者 &#x1f4d6;個人專欄&#xff1a; 《C語言》 《數據結構與算法》《C語言刷題集》《Leetcode刷題指南》 ??人生格言&#xff1a;生活是默默的堅持&#xff0c;毅力是永久的…

redis布隆過濾器解決緩存擊穿問題

在電商系統中&#xff0c;商品詳情頁是一個典型的高頻訪問場景。當用戶請求某個商品的詳情時&#xff0c;系統會優先從緩存中獲取數據。如果緩存中沒有該商品的詳情&#xff0c;系統會去數據庫查詢并更新緩存。然而&#xff0c;如果某個熱門商品的緩存失效&#xff0c;大量請求…

1+1>2!特征融合如何讓目標檢測更懂 “場景”?

來gongzhonghao【圖靈學術計算機論文輔導】&#xff0c;快速拿捏更多計算機SCI/CCF發文資訊&#xff5e;在多模態大模型&#xff08;MLLM&#xff09;時代&#xff0c;特征融合與目標檢測的研究方向正變得愈發關鍵。從紅外與可見光圖像的融合&#xff0c;到語音活動檢測中的特征…

詳解賽靈思SRIO IP并提供一種FIFO封裝SRIO的收發控制器仿真驗證

概述RapidIO標準定義為三層&#xff1a;邏輯層、傳輸層、物理層。邏輯層&#xff1a;定義總體協議和包格式&#xff0c;包含設備發起/完成事務的必要信息。傳輸層&#xff1a;提供包傳輸的路由信息&#xff08;對頂層不可見&#xff09;。物理層&#xff1a;描述設備級接口細節…

深度學習:簡介與任務分類總覽

一、什么是深度學習&#xff1f;1.1 深度學習的定義深度學習&#xff08;Deep Learning&#xff09;是機器學習的一種特殊形式&#xff0c;它依賴于具有多層結構的神經網絡自動從數據中學習特征并完成任務&#xff0c;如圖像識別&#xff0c;語音識別&#xff0c;自然語言處理等…

MSPM0開發學習筆記:二維云臺畫圖(2025電賽 附源代碼及引腳配置)

前言 今年的電賽&#xff08;2025&#xff09;&#xff0c;很多題都與云臺相關&#xff0c;因此為備戰電賽&#xff0c;博主這邊也是準備了一個由兩個42步進電機驅動的云臺并提前進行調試&#xff0c;避免賽題出來之后手忙腳亂的&#xff0c;這邊的兩個42步進電機采用同一個驅…

借助 Wisdom SSH 的 AI 助手構建 Linux 開發環境

借助Wisdom SSH的AI助手構建Linux開發環境 在Linux系統的開發場景中&#xff0c;快速、準確地搭建開發環境至關重要。Wisdom SSH憑借其強大的AI助手&#xff0c;能極大簡化這一過程&#xff0c;其官網為ssh.wisdomheart.cn。以下以在Ubuntu 22.04服務器上構建Python開發環境&am…

Python 程序設計講義(44):組合數據類型——集合類型:創建集合

Python 程序設計講義&#xff08;44&#xff09;&#xff1a;組合數據類型——集合類型&#xff1a;創建集合 目錄Python 程序設計講義&#xff08;44&#xff09;&#xff1a;組合數據類型——集合類型&#xff1a;創建集合一、集合的特征二、創建集合&#xff1a;使用set()函…

10 - 大語言模型 —Transformer 搭骨架,BERT 裝 “雙筒鏡”|解密雙向理解的核心

目錄 1、為什么 BERT 能 “懂” 語言&#xff1f;先看它的 “出身” 2、核心邏輯 2.1、“自學階段”—— 預訓練&#xff0c;像嬰兒學說話一樣積累語感 2.1.1、簡述 2.1.2、核心本事&#xff1a;“雙向注意力”&#xff0c;像人一樣 “聚焦重點” 2.2、“專項復習”—— …

【Spring Boot 快速入門】四、MyBatis

目錄MyBatis&#xff08;一&#xff09;入門簡介MyBatis 入門LombokMyBatis 基礎操作數據準備刪除預編譯新增更新查詢XML 映射文件MyBatis&#xff08;一&#xff09;入門 簡介 MyBatis 是一款 優秀的持久層框架&#xff0c;它支持 自定義 SQL、存儲過程以及高級映射&#xf…

Spring IOC 基于Cglib實現含構造函數的類實例化策略

作者&#xff1a;小凱 分享、讓自己和他人都能有所收獲&#xff01; 一、前言 技術成長&#xff0c;是對場景設計細節不斷的雕刻&#xff01; 你覺得自己的技術什么時候得到了快速的提高&#xff0c;是CRUD寫的多了以后嗎&#xff1f;想都不要想&#xff0c;絕對不可能&#xf…

composer 常用命令

### 設置鏡像源全局設置composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/當個項目設置composer config repo.packagist composer https://mirrors.aliyun.com/composer/恢復官方源composer config -g --unset repos.packagist### 常用源阿里云…

【python】Python爬蟲入門教程:使用requests庫

Python爬蟲入門教程&#xff1a;使用requests庫 爬蟲是數據獲取的重要手段&#xff0c;下面我將通過一個完整的示例&#xff0c;教你如何使用Python的requests庫編寫一個簡單的爬蟲。我們將以爬取豆瓣電影Top250為例。 【python】網絡爬蟲教程 - 教你用python爬取豆瓣電影 Top…

OpenCV圖像縮放:resize

圖像縮放是圖像處理中的基礎操作之一。無論是圖像預處理、數據增強還是圖像金字塔構建&#xff0c;cv::resize 都是我們最常用的函數之一。但你是否注意到&#xff0c;在 OpenCV 中同時還存在一個名為 cv::Mat::resize 的方法&#xff1f;這兩個函數雖然名字類似&#xff0c;但…

汽車、航空航天、適用工業虛擬裝配解決方案

一、現狀在制造業數字化轉型浪潮中&#xff0c;傳統裝配過程仍面臨諸多挑戰&#xff1a;物理樣機試錯成本高、裝配周期冗長、工藝優化依賴經驗、跨部門協作效率低下……如何打破“試錯-返工”的惡性循環&#xff1f;目前總裝工藝通過DELMIA、NX、Creo等工程軟件進行工藝裝配驗證…

頁面跳轉和前端路由的區別

傳統方式&#xff1a;通過改變瀏覽器地址欄的 URL 來實現window.location.href /new-page<a href"/new-page">跳轉到新頁面</a>會導致整個頁面重新加載會觸發瀏覽器向服務器發送新的請求頁面狀態不會保留&#xff0c;所有資源重新加載可以避免新上線的內…

C/C++核心知識點詳解

C/C核心知識點詳解 1. 變量的聲明與定義&#xff1a;內存分配的本質區別 核心概念 在C/C中&#xff0c;變量的聲明和定義是兩個完全不同的概念&#xff1a; 聲明&#xff08;Declaration&#xff09;&#xff1a;告訴編譯器變量的名稱和類型&#xff0c;但不分配內存空間定義&a…

物聯網發展:從概念到應用的演變歷程

物聯網的發展歷程是一部技術革新與社會需求共同驅動的進化史&#xff0c;其演變可劃分為概念萌芽、技術積累、應用拓展和智能融合四個階段&#xff0c;每個階段均以關鍵技術突破或社會需求變革為標志&#xff0c;最終形成萬物互聯的智能生態。以下是具體演變歷程&#xff1a;一…

一個人開發一個App(數據庫)

后端要保存數據&#xff0c;我還是選擇了關系型數據庫Mysql, 因為其它的不熟悉。 flutter端這次我選擇的是ObjectBox&#xff0c;以前都是直接用的sqlite3&#xff0c;看對比ObjectBox效率比sqlite3高許多&#xff0c;這次前端為了用戶體驗&#xff0c;我需要緩存數據&#xff…

天銘科技×藍卓 | “1+2+N”打造AI驅動的汽車零部件行業智能工廠

7月24日&#xff0c;杭州天銘科技股份有限公司&#xff08;簡稱 “天銘科技”&#xff09;與藍卓數字科技有限公司&#xff08;簡稱 “藍卓”&#xff09;簽訂全面戰略合作協議。天銘科技董事長張松、副總經理艾鴻冰&#xff0c;藍卓副董事長譚彰等領導出席簽約儀式&#xff0c…