紅黑樹:數據世界的平衡守護者

在 C++ 算法的神秘森林里,紅黑樹是一棵充滿智慧的 “魔法樹”。它既不像普通二叉搜索樹那樣容易失衡,也不像 AVL 樹對平衡要求那么苛刻。作為 C++ 算法小白,今天就和大家一起深入探索紅黑樹的奧秘,看看它是如何成為數據世界的平衡守護者的!?

紅黑樹是什么??

紅黑樹是一種自平衡的二叉搜索樹,它在每個節點上增加了一個存儲位來表示節點的顏色,可以是紅色或黑色。通過對樹的節點顏色進行約束,紅黑樹確保了樹在最壞情況下,依然能保持相對平衡,從而讓搜索、插入和刪除操作的時間復雜度穩定在 ?

O(logn)

。?

紅黑樹的規則?

  1. 節點顏色:每個節點要么是紅色,要么是黑色。?
  1. 根節點:根節點是黑色。?
  1. 葉子節點:每個葉子節點(NIL 節點,空節點)是黑色。?
  1. 紅色節點:如果一個節點是紅色的,那么它的兩個子節點都是黑色的。?
  1. 路徑黑色節點數:從任一節點到其每個葉子節點的所有路徑都包含相同數目的黑色節點。?

這五條規則就像是紅黑樹的 “生存法則”,讓它始終保持著良好的平衡狀態。可以把紅黑樹想象成一個嚴格遵守交通規則的城市,不同顏色的節點如同不同類型的車輛,在規則的約束下有序行駛,確保城市不會陷入混亂。?

紅黑樹的實現?

在 C++ 中,我們可以通過定義節點結構和相關操作來實現紅黑樹。以下是一個簡化版的紅黑樹實現代碼,并對關鍵部分進行詳細解釋。?

節點結構定義?

#include <iostream>// 定義紅黑樹節點結構
struct RBNode {int key;bool color;  // true 表示紅色,false 表示黑色RBNode* left;RBNode* right;RBNode* parent;RBNode(int k) : key(k), color(true), left(nullptr), right(nullptr), parent(nullptr) {}
};

每個節點包含鍵值 key 、顏色 color 、左右子節點指針 left 和 right ,以及父節點指針 parent 。節點默認顏色為紅色,因為新插入節點為紅色,在大多數情況下能減少調整操作。?

紅黑樹類定義與基本操作?

class RedBlackTree {
private:RBNode* root;// 左旋操作void leftRotate(RBNode* x) {RBNode* y = x->right;x->right = y->left;if (y->left != nullptr) {y->left->parent = x;}y->parent = x->parent;if (x->parent == nullptr) {root = y;} else if (x == x->parent->left) {x->parent->left = y;} else {x->parent->right = y;}y->left = x;x->parent = y;}// 右旋操作void rightRotate(RBNode* x) {RBNode* y = x->left;x->left = y->right;if (y->right != nullptr) {y->right->parent = x;}y->parent = x->parent;if (x->parent == nullptr) {root = y;} else if (x == x->parent->right) {x->parent->right = y;} else {x->parent->left = y;}y->right = x;x->parent = y;}// 插入節點后的修復操作void insertFixup(RBNode* z) {while (z != root && z->parent->color == true) {if (z->parent == z->parent->parent->left) {RBNode* y = z->parent->parent->right;if (y != nullptr && y->color == true) {z->parent->color = false;y->color = false;z->parent->parent->color = true;z = z->parent->parent;} else {if (z == z->parent->right) {z = z->parent;leftRotate(z);}z->parent->color = false;z->parent->parent->color = true;rightRotate(z->parent->parent);}} else {RBNode* y = z->parent->parent->left;if (y != nullptr && y->color == true) {z->parent->color = false;y->color = false;z->parent->parent->color = true;z = z->parent->parent;} else {if (z == z->parent->left) {z = z->parent;rightRotate(z);}z->parent->color = false;z->parent->parent->color = true;leftRotate(z->parent->parent);}}}root->color = false;}public:RedBlackTree() : root(nullptr) {}// 插入節點void insert(int key) {RBNode* z = new RBNode(key);RBNode* y = nullptr;RBNode* x = root;while (x != nullptr) {y = x;if (z->key < x->key) {x = x->left;} else {x = x->right;}}z->parent = y;if (y == nullptr) {root = z;} else if (z->key < y->key) {y->left = z;} else {y->right = z;}insertFixup(z);}// 中序遍歷void inorderTraversal(RBNode* node) {if (node != nullptr) {inorderTraversal(node->left);std::cout << node->key << " ";inorderTraversal(node->right);}}void inorderTraversal() {inorderTraversal(root);std::cout << std::endl;}
};
  1. 旋轉操作:左旋 leftRotate 和右旋 rightRotate 是紅黑樹保持平衡的重要手段。左旋以某個節點 x 為中心,將其右子節點 y 提升,x 變為 y 的左子節點;右旋則相反。就像在玩積木時,通過旋轉積木塊來調整結構,讓樹重新達到平衡。?
  1. 插入修復操作:insertFixup 函數在插入新節點后,根據紅黑樹規則進行調整。如果新插入節點的父節點是紅色,就可能違反規則,需要通過變色和旋轉操作來修復,確保樹滿足所有紅黑樹規則。?
  1. 插入節點:insert 函數先按照普通二叉搜索樹的方式找到插入位置,插入新節點后調用 insertFixup 進行修復,維持紅黑樹的平衡。?
  1. 中序遍歷:inorderTraversal 函數用于遍歷紅黑樹,按順序輸出節點的鍵值,方便查看樹的結構和內容。?

例題講解:使用紅黑樹實現動態數據集合管理?

問題描述?

假設我們需要管理一個動態的整數集合,要求能夠快速插入新元素,并按順序輸出集合中的所有元素。使用紅黑樹來實現這個功能。?

代碼示例?

int main() {RedBlackTree rbt;rbt.insert(5);rbt.insert(3);rbt.insert(7);rbt.insert(2);rbt.insert(4);rbt.insert(6);rbt.insert(8);std::cout << "Inorder traversal of the Red-Black Tree: ";rbt.inorderTraversal();return 0;
}

代碼解釋?

在 main 函數中,創建了一個紅黑樹對象 rbt ,然后依次插入多個整數。插入過程中,紅黑樹會自動調整結構,保持平衡。最后通過中序遍歷,按順序輸出紅黑樹中的所有節點鍵值,得到有序的整數集合。?

紅黑樹在很多場景都有重要應用,比如 C++ 標準庫中的 map 和 set ,底層實現就用到了紅黑樹。它憑借高效的平衡維護和穩定的時間復雜度,成為了數據管理的得力助手。作為 C++ 算法小白,掌握紅黑樹的原理和應用,能讓我們在算法學習和編程實踐中更上一層樓!

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

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

相關文章

【hot100-動態規劃-139.單詞拆分】

力扣139.單詞拆分 本題要求判斷給定的字符串 s 是否可以被空格拆分為一個或多個在字典 wordDict 中出現的單詞,且不要求字典中出現的單詞全部都使用,并且字典中的單詞可以重復使用,這是一個典型的動態規劃問題。 動態規劃思路 定義狀態: 定義一個布爾類型的數組 dp,其中…

ZFile與Cpolar技術結合實現遠程數據實時訪問與集中管理的可行性分析

文章目錄 前言1.關于ZFile2.本地部署ZFile3.ZFile本地訪問測試4.ZFile的配置5.cpolar內網穿透工具安裝6.創建遠程連接公網地址7.固定ZFile公網地址 前言 在信息爆炸的年代&#xff0c;每個現代人都在數字浪潮中扮演著獨特的角色。不論是商務精英、影像創作者還是學術達人&…

Vue2在子組件上使用v-model實現數據的雙向綁定、.sync修飾符

1、v-model 先看示例&#xff1a; //父組件<template><ChildComponent v-model"parentData" /> </template><script> import ChildComponent from ./ChildComponent.vue;export default {components: {ChildComponent},data() {return {pa…

自學嵌入式 day 18 - 數據結構 1

數據結構 相互之間存在一種或多種特定關系的數據元素的集合 1.特定關系&#xff1a; &#xff08;1&#xff09;邏輯結構&#xff1a; ①集合&#xff1a;所有在同一個集合中&#xff0c;關系平等。 ②線性關系&#xff1a;數據和數據之間是一對一的關系。&#xff08;數組…

《Java 大視界——Java 大數據在智能電網分布式能源協同調度中的應用與挑戰》

隨著風電、光伏等分布式能源大規模接入電網&#xff0c;傳統調度系統面臨數據規模激增、響應延遲顯著、多源異構數據融合困難等核心問題。本文聚焦Java生態下的大數據技術體系&#xff0c;深入探討其在智能電網實時監測、負荷預測、資源優化配置等場景中的落地實踐。通過分析Sp…

解密企業級大模型智能體Agentic AI 關鍵技術:MCP、A2A、Reasoning LLMs-MCP大模型上下文解析

解密企業級大模型智能體Agentic AI 關鍵技術&#xff1a;MCP、A2A、Reasoning LLMs-MCP大模型上下文解析 我們首先來看一下 整個MCP的一個基本的一個流程&#xff0c;他解決的一個問題。我們回到這里&#xff0c;他解決的一個問題是什么呢&#xff1f;他解決這個問題就是你的大…

25.5.15

沒有比水題更令人開心的事情了 典型的并查集題目&#xff0c;并查集分為并和查&#xff0c;并就是把有關系的父親根結點設為同一個&#xff0c;查就是在成功構造后對其進行查詢 查通過遞歸實現 if (x f[x])return x; return f[x] find(f[x]); 由于并查集的特點&#xff0…

低損耗高效能100G O Band DWDM 10km光模塊 | 支持密集波分復用

目錄 前言 一、產品概述 100G QSFP28 O Band DWDM 10km光模塊核心特點包括&#xff1a; 二、為何選擇O Band DWDM方案&#xff1f; 1.低色散損耗&#xff0c;傳輸更穩定 2.兼容性強 三、典型應用場景 1.數據中心互聯&#xff08;DCI&#xff09; 2.企業園區/智慧城市組網 3.電信…

CentOS 7 內核升級指南:解決兼容性問題并提升性能

點擊上方“程序猿技術大咖”&#xff0c;關注并選擇“設為星標” 回復“加群”獲取入群討論資格&#xff01; CentOS 7 默認搭載的 3.10.x 版本內核雖然穩定&#xff0c;但隨著硬件和軟件技術的快速發展&#xff0c;可能面臨以下問題&#xff1a; 硬件兼容性不足&#xff1a;新…

計算機視覺----基礎概念、卷積

一、概述 1.計算機視覺的定義 計算機視覺(Computer Vision)是一個跨學科的研究領域,主要涉及如何使計算機能夠通過處理和理解數字圖像或視頻來自動進行有意義的分析和決策。其目標是使計算機能夠從視覺數據中獲取高層次的理解,類似于人類的視覺處理能力。 具體來說,計算機…

2025認證杯數學建模第二階段C題:化工廠生產流程的預測和控制,思路+模型+代碼

2025認證杯數學建模第二階段思路模型代碼&#xff0c;詳細內容見文末名片 一、探秘化工世界&#xff1a;問題背景大揭秘 在 2025 年 “認證杯”數學中國數學建模網絡挑戰賽第二階段 C 題中&#xff0c;我們一頭扎進了神秘又復雜的化工廠生產流程預測與控制領域。想象一下&…

關于AI人工智能的知識圖譜簡介

人工智能是計算機科學的一個重要領域&#xff0c;旨在理解和構建智能行為。人工智能可以被劃分為多個子領域或分支&#xff0c;包括機器學習、深度學習、自然語言處理&#xff08;Natural Language Processing&#xff0c;NLP&#xff09;、計算機視覺&#xff08;Computer Vis…

巧妙利用redis防爆破

爆破&#xff0c;也就是通過海量的嘗試&#xff0c;最終確定密碼&#xff0c;人們設置密碼具有習慣性&#xff0c;好記、簡單、有象征等&#xff0c;也就有密碼字典一說&#xff0c;但是該字典也是巨量的&#xff0c;但是相對于各種字母符號等組合就顯得輕量非常多 在Java Spr…

Uniapp開發鴻蒙購物項目教程之樣式選擇器

大家好&#xff0c;今天依然為大家帶來鴻蒙跨平臺開發教程的分享&#xff0c;我們本系列的教程最終要做一個購物應用&#xff0c;通過這個項目為大家分享uniapp開發鴻蒙應用從配置開發環境到應用打包上架的完成過程。 昨天的文章實現了應用首頁的輪播圖&#xff0c;其中涉及到…

2、ubantu系統配置OpenSSH | 使用vscode或pycharm遠程連接

1、OpenSSH介紹 OpenSSH&#xff08;Open Secure Shell&#xff09;是一套基于SSH協議的開源工具&#xff0c;用于在計算機網絡中提供安全的加密通信。它被廣泛用于遠程系統管理、文件傳輸和網絡服務的安全隧道搭建&#xff0c;是保護網絡通信免受竊聽和攻擊的重要工具。 1.1…

Leetcode刷題 | Day63_圖論08_拓撲排序

一、學習任務 拓撲排序代碼隨想錄 二、具體題目 1.拓撲排序117. 軟件構建 【題目描述】 某個大型軟件項目的構建系統擁有 N 個文件&#xff0c;文件編號從 0 到 N - 1&#xff0c;在這些文件中&#xff0c;某些文件依賴于其他文件的內容&#xff0c;這意味著如果文件 A 依…

uniapp中vue3和pinia安裝依賴npm install失敗

目錄 一、問題描述 二、問題原因 三、問題解析及解決方案 一、問題描述 用uni-app開發小程序的時候&#xff0c;使用了vue3pinia,安裝依賴的時候發現vue和pinia的版本問題&#xff0c;安裝失敗&#xff0c; npm ERR! code ERESOLVE npm ERR! ERESOLVE could not resolve np…

2025認證杯第二階段數學建模B題:謠言在社交網絡上的傳播思路+模型+代碼

2025認證杯數學建模第二階段思路模型代碼&#xff0c;詳細內容見文末名片 一、引言 在當今數字化時代&#xff0c;社交網絡已然成為人們生活中不可或缺的一部分。信息在社交網絡上的傳播速度猶如閃電&#xff0c;瞬間就能觸及大量用戶。然而&#xff0c;這也為謠言的滋生和擴…

【C#】Thread.Join()、異步等待和直接join

JogThread.Join() 是 .NET 中 System.Threading.Thread 類的一個方法&#xff0c;用來讓當前調用線程暫停執行&#xff0c;直到目標線程&#xff08;這里是 JogThread&#xff09;終止為止。以下是它的核心語義和你在 UI 代碼里需要注意的幾個相關知識點。 1. Thread.Join() 的…

牛客網NC22012:判斷閏年問題詳解

牛客網NC22012&#xff1a;判斷閏年問題詳解 &#x1f4dd; 題目描述 題號&#xff1a;NC22012&#xff08;牛客網&#xff09; 時間限制&#xff1a;C/C/Rust/Pascal 1秒&#xff0c;其他語言2秒 空間限制&#xff1a;C/C/Rust/Pascal 32 M&#xff0c;其他語言64 M 判斷一個…