紅黑樹詳解

紅黑樹的概念與性質

?前置知識

在學習紅黑樹之前,最好有二叉查找樹和AVL樹的基礎,因為紅黑樹本質就是一種特殊的二叉查找樹,而紅黑樹的操作中需要用到AVL樹中旋轉的相關知識。至于二叉查找樹和AVL樹,可以參考如下兩篇博客:

二叉查找樹:二叉查找樹-CSDN博客

AVL樹:AVL樹詳解_avl tree-CS? DN博客


紅黑樹是一種特殊的二叉查找樹,顧名思義,紅黑樹的一個特性就是每個節點都有一個顏色特征,或為紅或為黑。紅黑樹可以通過一系列的限制規則保證最長路徑小于最短路徑的兩邊,也就是說,紅黑樹的每一條路徑長度的范圍為[N, 2N],其中N為最短路徑長度。

與AVL樹不同的是,紅黑樹并不是嚴格意義上的平衡二叉樹,降低了插入和旋轉的次數,所以在經常進行增刪的結構中性能比AVL樹更優。

紅黑樹是通過如下5條性質/規則來維護的:

  1. 每個結點不是紅色就是黑色
  2. 根節點必須是黑色的
  3. 紅色節點的孩子結點只能是黑色的,即路徑上不能出現兩個連續的紅節點
  4. 從任一節點到其每個葉子的所有路徑,要包含相同數目的黑色節點
  5. 所有的葉子結點都是黑結點

注意,由于翻譯的問題,這里的葉子節點實際上指的其實是NIL節點(空節點)。所以,第5條并不算是一條規則,而是一個性質的說明。

那么為什么說這幾條性質就保證了最長路徑不會大于最短路徑的二倍呢?首先,根節點一定是黑的就保證了每條路徑的開始都是一個黑色節點。不能出現連續的紅節點而且每條路徑的黑色結點數量要保持一致,這種的話最短路徑的情況就是整條路徑都為黑色的情況,而最長路徑的情況就是一黑后面緊跟著一紅結點。所以我們很容易應證,最長路徑不會超過最短路徑的二倍。

紅黑樹的插入

紅黑樹本質上就是一種特殊的二叉查找樹,所以大綱上我們依舊是按照二叉查找樹的方式來插入。但是特別的,紅黑樹還維護了結點的顏色這一特性,所以我們還需要額外維護結點的顏色已經遵循上述的條規則/性質。

首先我們要思考,插入新結點時,是將其初始化為紅色還是黑色。我們知道紅黑樹要控制每條路徑的黑色結點相同,所以為了安全起見,一般是插入節點都默認初始化為紅色節點。特別的,紅黑樹還要保證根節點為黑色,所以我們還需要對根節點的情況特殊處理。也就是說,除了根節點的情況外,新插入的結點都是統一初始化為紅色,后續就根據具體情況具體調整了。

那么新插入結點默認為紅結點,就必然會出現插入之后連續兩個紅色結點的情況,那么我們可以將插入之后出現連續紅色結點的各種情況分為兩大類來說:

首先我們規定,cur為當前新插入的節點,p為父節點,g為祖父節點,u為叔叔節點。

  • 情況1:cur為紅,p為紅,u存在且為紅,g為黑

這里需要解釋一下,cur為新插入節點,如果p是紅的,那么根據紅黑樹的性質,g一定是黑的。這種叔叔節點存在且為紅的情況比較好處理,只需要讓父親節點p和叔叔節點u的顏色置黑,g節點置黑即可。

首先,把p和u置黑是因為不能出現連續的紅色節點。而把g置紅是因為g并不一定就是根節點,所以為了不影響本條路徑的黑色節點的數量,是需要將p置紅的。那么如果g真的為根節點的話不就又與性質沖突了嗎?所以我們需要特殊情況特殊處理,一般來說前面照常操作,最后之間暴力將根節點顏色設置為黑色是一種較為簡便好理解的方式。

我們要知道,紅黑樹節點調整要在保證不改變路徑上黑色節點數量的情況下進行調整,所以當叔叔節點存在且為紅的時候,我們就可以通過將叔叔節點置黑,使得在保證路徑上黑色節點數量不變的前提下,調整兩個連續的紅色節點。

  • 情況2:cur為紅,p為紅,g為黑,u不存在/u存在且為黑

那么當叔叔節點為黑色呢?這時我們就無法直接通過簡單顏色來進行調整了,此時就需要用到AVL樹中提到的4個旋轉了。根據p和cur的位置,共有四種旋轉的情況。不過由于雙旋與單旋之后原來g位置的節點可能為cur也可能為p,所以我們這時就不能單純的將cur置紅或置黑。而是將旋轉之后原g位置的節點置黑,將其兩個子節點置紅,叔叔節點一直是黑的或者空,所以不用對其處理。

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

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

相關文章

oracle安裝的肘腋之疾小合集

#臨時空間指定 export TMP/tmp export TMPDIR/tmp #圖形化顯示框不全 java問題,使用系統自帶的jre ./runInstaller -jreLoc/usr/local/jdk1.7.0_80/ #ins30131 Failed to access the temporary location 給/tmp/CVU*加x權限 #linux桌面太小 xrandr -s 1440x900_60…

Matplotlib圖形注釋_Python數據分析與可視化

Matplotlib圖形注釋 添加注釋文字、坐標變換 有的時候單單使用圖形無法完整清晰的表達我們的信息,我們還需要進行文字進行注釋,所以matplotlib提供了文字、箭頭等注釋可以突出圖形中重點信息。 添加注釋 為了使我們的可視化圖形讓人更加容易理解&#…

vue中父組件直接調用子組件方法

vue2 中&#xff0c;父組件如何調用子組件的方法 在Vue 2中&#xff0c;父組件可以通過使用ref屬性來引用子組件的實例&#xff0c;然后通過該實例調用子組件的方法。 首先&#xff0c;在父組件的模板中&#xff0c;給子組件添加一個ref屬性&#xff1a; <template>&l…

在工業生產環境下,服務器沒有互聯網,如何通過代理自己的電腦上互聯網?

服務器主機是CentOS7操作系統.&#xff0c;服務器的局域網是10.0.6.x網段。我的筆記本的以太網口的局域網ip是也是10.0.6.x&#xff0c;由于這個10.0.6.x的整個局域網是沒有撥號上網的所有無法訪問互聯網。 但是&#xff0c;如果筆記本臉上wifi&#xff0c;wifi的網段是192.168…

長度最小的子數組

給定一個含有 n 個正整數的數組和一個正整數 target 。 找出該數組中滿足其總和大于等于 target 的長度最小的 連續子數組 [numsl, numsl1, …, numsr-1, numsr] &#xff0c;并返回其長度。如果不存在符合條件的子數組&#xff0c;返回 0 。 示例 1&#xff1a; 輸入&#x…

MySQL 有多個普通索引時會取哪一個索引?

我們都知道MySQL在查詢時底層會進行索引的優化&#xff0c;假設有兩個普通索引&#xff0c;且where 后面也根據這兩個普通索引查詢數據&#xff0c;那么執行查詢語句時會使用到那個索引&#xff1f; 為了方便演示&#xff0c;新建users表&#xff0c;新建idx_name、idx_city這兩…

前端vue導出PPT,使用pptxgen.js

前言 公司新需求需要導出ppt給業務用&#xff0c;查閱資料后發現也挺簡單的&#xff0c;記錄一下。 如有不懂的可以留言&#xff01;&#xff01;&#xff01; 1.安裝包 npm install pptxgenjs --save2.引入包 在需要使用的文件中引入 import Pptxgenfrom "pptxgenjs&…

Oracle研學-介紹及安裝

一 ORACLE數據庫特點: 支持多用戶&#xff0c;大事務量的事務處理數據安全性和完整性控制支持分布式數據處理可移植性(跨平臺&#xff0c;linux轉Windows) 二 ORACLE體系結構 數據庫&#xff1a;oracle是一個全局數據庫&#xff0c;一個數據庫可以有多個實例&#xff0c;每個…

nodejs+vue+python+PHP+微信小程序-留學信息查詢系統的設計與實現-安卓-計算機畢業設計

1、用戶模塊&#xff1a; 1&#xff09;登錄&#xff1a;用戶注冊登錄賬號。 2&#xff09;留學查詢模塊&#xff1a;查詢學校的入學申請條件、申請日期、政策變動等。 3&#xff09;院校排名&#xff1a;查詢國外各院校的實力排名。 4&#xff09;測試功能&#xff1a;通過入學…

Spring Boot WebSocket 客戶端

介紹 WebSocket 是一種在單個 TCP 連接上進行全雙工通信的協議&#xff0c;它可以提供實時的、雙向的數據傳輸。Spring Boot 提供了對 WebSocket 的支持&#xff0c;我們可以使用 Spring Boot WebSocket 客戶端來連接到 WebSocket 服務器&#xff0c;并進行實時通信。 本文將…

python-選擇排序

選擇排序是一種簡單直觀的排序算法&#xff0c;它的基本思想是每一輪選擇未排序部分的最小元素&#xff0c;然后將其放到已排序部分的末尾。這個過程持續進行&#xff0c;直到整個數組排序完成。(重點&#xff1a;通過位置找元素) 以下是選擇排序的詳細步驟和 Python 實現&…

HarmonyOS應用開發實戰—登錄頁面【ArkTS】

文章目錄 本頁面實戰效果預覽圖一.HarmonyOS應用開發1.1HarmonyOS 詳解1.2 ArkTS詳解二.HarmonyOS應用開發實戰—登錄頁面【ArkTS】2.1 ArkTS頁面源碼2.2 代碼解析2.3 心得本頁面實戰效果預覽圖 一.HarmonyOS應用開發 1.1HarmonyOS 詳解 HarmonyOS(鴻蒙操作系統)是華為公司…

小程序首頁白屏優化,并舉例說明

小程序首頁白屏優化 小程序首頁白屏優化是指在用戶進入小程序首頁時&#xff0c;能夠盡快展示內容&#xff0c;避免出現長時間的白屏加載狀態&#xff0c;提升用戶體驗。以下是一些常見的小程序首頁白屏優化方法&#xff1a; 減少首屏請求&#xff1a;盡量減少首頁需要請求的資…

js粒子效果(一)

效果: 代碼: <!doctype html> <html> <head><meta charset"utf-8"><title>HTML5鼠標經過粒子散開動畫特效</title><style>html, body {position: absolute;overflow: hidden;margin: 0;padding: 0;width: 100%;height: 1…

DELL MD3600F存儲重置管理軟件密碼

注意&#xff1a;密碼清除可能會導致業務秒斷&#xff0c;建議非業務時間操作 針對一臺控制器操作即可&#xff0c;另一控制器會同步操作 重置后密碼為空&#xff01; 需求&#xff1a;重置存儲管理軟件密碼 管理軟件中分配物理磁盤時提示輸入密碼(類似是否了解風險確認操作的提…

華為OD機試 - 二叉樹計算(Java JS Python C)

目錄 題目描述 輸入描述 輸出描述 用例 題目解析 JS算法源碼 Java算法源碼

io.lettuce.core.RedisCommandExecutionException

io.lettuce.core.RedisCommandExecutionException: ERR invalid password ERR invalid password-CSDN博客 io.lettuce.core.RedisCommandExecutionException /** Copyright 2011-2022 the original author or authors.** Licensed under the Apache License, Version 2.0 (the…

Rust UI開發(一):使用iced構建UI時,如何在界面顯示中文字符

注&#xff1a;此文適合于對rust有一些了解的朋友 iced是一個跨平臺的GUI庫&#xff0c;用于為rust語言程序構建UI界面。 iced的基本邏輯是&#xff1a; UI交互產生消息message&#xff0c;message傳遞給后臺的update&#xff0c;在這個函數中編寫邏輯&#xff0c;然后通過…

2023-11-24--oracle--實驗--[Merge 語句]

oracle--實驗---Merge語句 1.認知Merge 語句 ? merge 語句是 sql 語句的一種。在 SQL server 、 Oracle 數據庫中可用&#xff0c; MySQL 中不可用。 ? merge 用來合并 update 和 insert 語句。目的&#xff1a;通過 merge 語句&#xff0c;根據一張表&#xff08; 原數據表…

IOS免簽封裝打包蘋果APP的方法

IOS免簽app封裝打包蘋果APP的方法如下&#xff1a; 準備一個未簽名的IPA文件。獲取一個企業證書或個人證書&#xff0c;用于簽名IPA文件。將證書添加到Keychain Access中。安裝iOS App Signer&#xff08;可以在網上找到相關下載鏈接&#xff09;。打開iOS App Signer&#xf…