色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

如何使用 go 實現紅黑樹

Linux愛好者 ? 來源:Linux愛好者 ? 作者:Linux愛好者 ? 2022-03-21 11:54 ? 次閱讀

本文介紹了使用 go 實現紅黑樹。

二叉搜索樹(二叉查找樹)

二叉查找樹也叫二叉搜索樹,也叫二叉排序樹,它具有以下特點:1. 如果左子樹不為空,則左子樹上的結點的值都小于根節點;2. 如果右子樹不為空,則右子樹上的結點的值都大于根節點;3. 子樹同樣也要遵循以上兩點。

二叉樹的遍歷方式

二叉樹的遍歷方式:前序遍歷、中序遍歷、后序遍歷和層序遍歷(MySql)。

只要一棵樹是二叉查找樹,那么它的中序遍歷(左根右輸出)一定是有序的。比如看下邊的一棵二叉樹:

a132bac4-9330-11ec-952b-dac502259ad0.jpg

它的前序遍歷(根左右)為:530468;
它的中序遍歷(左根右)為:034568;
它的后序遍歷(左右根)為:043865。

二叉搜索樹有哪些應用?

既然是搜索樹,那么它肯定就是用在查找上。我們來分析下它的查找時間復雜度:

先來看下面兩顆二叉搜索樹:

a143adac-9330-11ec-952b-dac502259ad0.jpg

查找時間復雜度其實就是樹的深度。

上圖一的時間復雜度:O(n)時間復雜度,表示需要查找 n 次,即循環 n 遍,退化成鏈表的情況。

上圖二的時間復雜度(類似二分查找):logn,即 => x= => logn。

那么為什么會出現退化成鏈表的情況(圖一)呢?我們該怎么處理才不會變成鏈表呢(怎么解決)?

當插入的節點數值從小到大時,則就會出現二叉樹退化成鏈表的情況,那么有另一種樹可以解決這種情況,就是平衡二叉樹(AVL樹)。

AVL樹是一種追求極致平衡的二叉搜索樹,即將樹調整到最優的情況,由于這種樹結構比較苛刻、旋轉也比較多,這里就不重點展開講。

紅黑樹

紅黑樹的由來

今天需要重點講的是紅黑樹。紅黑樹的底層數據結構其實就是二叉查找樹,也就是說紅黑樹是一顆特殊的二叉查找樹,也叫自平衡二叉查找樹

紅黑樹出現的目的就是上所講到的,為了解決二叉樹退化成鏈表的情況。

紅黑樹的演進過程

鏈表(暴力查處) -> 二叉樹 -> 二叉查找樹 -> 特殊的二叉查找樹(自平衡的二叉查找樹)

紅黑色講解

通過上面的例子以及兩個圖,我們發現二叉樹的結構就決定了其搜索的效率及性能,那么我們需要怎么樣才讓二叉樹達到優化的效果呢?

因此就有了紅黑樹了,我們看下圖(紅黑樹):

a15f25c8-9330-11ec-952b-dac502259ad0.jpg

紅黑樹的性質:

每個節點不是紅色就是黑色(這里不一定要紅色和黑色,只要知道這里的紅色和黑色是什么意思即可)

一定沒有連在一起的紅色節點

根節點(第一個節點)是黑色 root

每個紅色節點的兩個字節點都是黑色

葉子結點都是黑色(上圖中其實還有為null的葉子結點沒有畫出來),如下圖所示:

a1753dae-9330-11ec-952b-dac502259ad0.jpg

根據以上性質或者說滿足了以上性質的樹,就可以達到近似平衡了。

怎么判斷一個節點是否為根結點?

沒有父節點

入度為0的節點

紅黑樹變換規則

要滿足這些性質,需要對樹做什么操作呢?

為了紅黑可以滿足這些性質,因此出現了旋轉,那么紅黑樹有幾種變換規則呢?

有三種變換規則:

變色:紅變黑 黑變紅

左旋轉

右旋轉

左旋轉示例:

a1892648-9330-11ec-952b-dac502259ad0.jpg

旋轉和顏色變換規則:所有插入的點默認為紅色; 1. 變顏色的情況:如果插入的節點的父節點和叔叔節點為紅色,則:1)把父節點和叔叔節點設為黑色;2)把爺爺(祖父)節點設為紅色;3)把指針定位到爺爺節點作為當前需要操作的節點,再根據變換規則來進行判斷操作。2. 左旋:如果當前父節點是紅色,叔叔節點是黑色,而且當前的節點是右子樹時,則需要以父節點作為左旋轉。3. 右旋:當前父節點是紅色,叔叔節點是黑色,且當前的節點是左子樹時,則:1)把父節點變為黑色;2)把爺爺節點變為紅色;3)以父節點右旋轉。

a19a2f92-9330-11ec-952b-dac502259ad0.jpg

比如要往上圖中插入數字6,則這顆紅黑色的演變過程如下:

step1: 插入6節點后如下圖,它的父節點和叔叔節點均是紅色,則需要根據變換規則來操作,到step2了。

a1a952c4-9330-11ec-952b-dac502259ad0.jpg

step2: 根據變換規則,需要將插入節點的父節點和叔叔節點均變為黑色,爺爺節點變為紅色,然后將指針定位到爺爺節點(藍色圈)。將指針定位到爺爺節點(12)后,此時做為當前需要操作的節點,再根據變換規則來判斷,可以看到下圖的當前節點(12)的叔叔節點是黑色的,則不能用變顏色規則的情況了,進行step3,此時需要進行左旋或右旋了。

a1b9a8fe-9330-11ec-952b-dac502259ad0.jpg

step3: 根據上圖情況可以知道此時是符合左旋規則的:當前節點(12)的父節點(5)是紅色,叔叔節點(3)是黑色,而且當前的節點是右子樹。接下來需要進行左旋變換(三步走):

a1cd5ade-9330-11ec-952b-dac502259ad0.jpg

step4:左旋變換后,可以看到當前節點(5)的父節點(12)為紅色,叔叔節點(30)為黑色,而且當前節點為左子樹,符合右旋的規則。接下來就是進行右旋的變換操作了:1)把父節點(12)變為黑色;2)把爺爺節點(29)變為紅色;3)以父節點(12)右旋轉

a1dc228a-9330-11ec-952b-dac502259ad0.jpg

小結

到這里,可以看到經過多次旋轉后,這棵樹是符合紅黑色的性質。

Golang代碼實現紅黑樹

直接上代碼,如下:

packagemain

import(
"fmt"
"math/rand"
"time"
)

const(
REDbool=true
BLACKbool=false
)

typeNodestruct{
keyint
valueinterface{}

left*Node
right*Node
//parent*Node

colorbool
}

typeRedBlackTreestruct{
sizeint
root*Node
}

funcNewNode(key,valint)*Node{
//默認添加紅節點
return&Node{
key:key,
value:val,
left:nil,
right:nil,
//parent:nil,
color:RED,
}
}

funcNewRedBlackTree()*RedBlackTree{
return&RedBlackTree{}
}

func(n*Node)IsRed()bool{
ifn==nil{
returnBLACK
}
returnn.color
}

func(tree*RedBlackTree)GetTreeSize()int{
returntree.size
}

//nodex
///左旋轉/
//T1x--------->nodeT3
////
//T2T3T1T2
func(n*Node)leftRotate()*Node{
//左旋轉
retNode:=n.right
n.right=retNode.left

retNode.left=n
retNode.color=n.color
n.color=RED

returnretNode
}

//nodex
///右旋轉/
//xT2------->ynode
////
//yT1T1T2
func(n*Node)rightRotate()*Node{
//右旋轉
retNode:=n.left
n.left=retNode.right

retNode.right=n
retNode.color=n.color
n.color=RED

returnretNode
}

//顏色變換
func(n*Node)flipColors(){
n.color=RED
n.left.color=BLACK
n.right.color=BLACK
}

//維護紅黑樹
func(n*Node)updateRedBlackTree(isAddint)*Node{
//isAdd=0說明沒有新節點,無需維護
ifisAdd==0{
returnn
}

//需要維護
ifn.right.IsRed()==RED&&n.left.IsRed()!=RED{
n=n.leftRotate()
}

//判斷是否為情形3,是需要右旋轉
ifn.left.IsRed()==RED&&n.left.left.IsRed()==RED{
n=n.rightRotate()
}

//判斷是否為情形4,是需要顏色翻轉
ifn.left.IsRed()==RED&&n.right.IsRed()==RED{
n.flipColors()
}

returnn
}

//遞歸寫法:向樹的root節點中插入key,val
//返回1,代表加了節點
//返回0,代表沒有添加新節點,只更新key對應的value值
func(n*Node)add(key,valint)(int,*Node){
ifn==nil{//默認插入紅色節點
return1,NewNode(key,val)
}

isAdd:=0
ifkeyn.key{
isAdd,n.right=n.right.add(key,val)
}else{
//對value值更新,節點數量不增加,isAdd=0
n.value=val
}

//維護紅黑樹
n=n.updateRedBlackTree(isAdd)

returnisAdd,n
}

func(tree*RedBlackTree)Add(key,valint){
isAdd,nd:=tree.root.add(key,val)
tree.size+=isAdd
tree.root=nd
tree.root.color=BLACK//根節點為黑色節點
}

//前序遍歷打印出key,val,color
func(tree*RedBlackTree)PrintPreOrder(){
resp:=make([][]interface{},0)
tree.root.printPreOrder(&resp)
fmt.Println(resp)
}

func(n*Node)printPreOrder(resp*[][]interface{}){
ifn==nil{
return
}
*resp=append(*resp,[]interface{}{n.key,n.value,n.color})
n.left.printPreOrder(resp)
n.right.printPreOrder(resp)
}


//測試紅黑樹代碼
funcmain(){
count:=10
redBlackTree:=NewRedBlackTree()
nums:=make([]int,0)
fori:=0;i

測試輸出結果如下:

datasource:[1779185060]
redBlackTree:-2.136μs
[[77false][11true][00false][66false][55true][99false][88true]]
節點數量:7

總結

紅黑樹是保持近似平衡的二叉樹,從另一種角度上來說紅黑樹不是平衡二叉樹,它的最大高度為2*logn。

二分搜索樹,AVL樹,紅黑樹對比:1. 對于完全隨機的數據源,普通二分搜索樹很好用,缺陷是在極端情況下容易退化成鏈表 2. 對于查詢較多的使用情況,AVL樹很好用,因為他的高度一直保持h=logn 3. 紅黑樹犧牲了平衡性,即h=2*logn,但在添加和刪除操作中,紅黑樹比AVL樹有優勢 4. 綜合增刪改查所有操作,紅黑樹的統計性能更優

原文標題:二叉樹、紅黑樹以及Golang實現紅黑樹

文章出處:【微信公眾號:Linux愛好者】歡迎添加關注!文章轉載請注明出處。

審核編輯:彭菁

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 代碼
    +關注

    關注

    30

    文章

    4821

    瀏覽量

    68890
  • 數據源
    +關注

    關注

    1

    文章

    63

    瀏覽量

    9709
  • 二叉樹
    +關注

    關注

    0

    文章

    74

    瀏覽量

    12362

原文標題:二叉樹、紅黑樹以及Golang實現紅黑樹

文章出處:【微信號:LinuxHub,微信公眾號:Linux愛好者】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    Go語言實現敏感詞檢測(前綴

    大家都知道游戲文字、文章等一些風控場景都實現了敏感詞檢測,一些敏感詞會被屏蔽掉或者文章無法發布。今天我就分享用Go實現敏感詞前綴來達到文本的敏感詞檢測,讓我們一探究竟!
    發表于 10-31 10:22 ?1247次閱讀

    驗功放時將輸出端柱短路,為什么會燒功放

    驗功放時將輸出端柱短路,為什么會燒功放
    發表于 08-26 18:54

    什么是“”看了就知道

    今天我們要說的就是就是一棵非嚴格均衡的二叉,均衡二叉又是在二叉搜索的基礎上增加了自動
    發表于 10-27 17:00

    Linux下一種高性能定時器池的實現

    提出Linux用戶空間下的一種高性能定時器池的實現方法。主要基于時間輪、及Linux內核提供了一種利于管理的定時器句柄Timerfd。結合
    發表于 09-25 14:57 ?25次下載

    一文詳解

    界應用很廣泛,比如 Java 中的 TreeMap,JDK 1.8 中的 HashMap、C++ STL 中的 map 均是基于樹結構實現的。考慮到
    的頭像 發表于 02-02 17:25 ?4242次閱讀
    一文詳解<b class='flag-5'>紅</b><b class='flag-5'>黑</b><b class='flag-5'>樹</b>

    詳解電源二叉到底是什么

    作為數據結構的基礎,分很多種,像 AVL 、二叉搜索....今天我想分享的是關于二
    的頭像 發表于 06-06 15:05 ?1w次閱讀
    詳解電源二叉<b class='flag-5'>樹</b>到底是什么

    魔3和鯊2買哪個好

    鯊2還是魔3?作為兩款同樣采用高通驍龍855移動平臺的游戲手機,鯊2和魔3不免會被消費者放在一起進行比較。那么,鯊2和
    的頭像 發表于 07-04 14:43 ?1.4w次閱讀

    鯊2和魔3哪個好

    魔3和鯊2哪個好?和鯊科技今年上半年力推的“鯊2”一樣,魔3也搭載了高通驍龍855移動平臺。那么,
    的頭像 發表于 06-30 09:20 ?2.1w次閱讀

    魔Mars和鯊Helo哪個最好

    在18年的圈里,游戲手機燃起了很大的熱點,尤其是鯊和魔更是打動很多手游愛好者,進化后的魔Mars和鯊Helo更是棋逢對手,如今令人期待的
    的頭像 發表于 07-11 11:43 ?3636次閱讀

    (Red Black Tree)是一種自平衡的二叉搜索

    平衡(Balance):就是當結點數量固定時,左右子樹的高度越接近,這棵二叉越平衡(高度越低)。而最理想的平衡就是完全二叉/滿二叉,高度最小的二叉
    的頭像 發表于 07-01 15:05 ?5780次閱讀
    <b class='flag-5'>紅</b><b class='flag-5'>黑</b><b class='flag-5'>樹</b>(Red Black Tree)是一種自平衡的二叉搜索<b class='flag-5'>樹</b>

    Go并發模型的實現原理

    Go語言是為并發而生的語言,Go語言是為數不多的在語言層面實現并發的語言;也正是Go語言的并發特性,吸引了全球無數的開發者。
    的頭像 發表于 04-15 08:49 ?1415次閱讀

    是如何模擬2-3 B的操作邏輯的

    大家都聽說過,也都知道很厲害,是計算機里面評價非常高的數據結構。但是每當想學習
    的頭像 發表于 08-30 10:22 ?905次閱讀

    Unitree Go2四足機器人:智能科技新選擇

    7月12日,宇推出了備受矚目的Unitree Go2四足機器人,售價從9997元起。這款產品將徹底改變以往消費級四足機器人的市場格局,并引領整個行業的變革。早在2021年6月,宇就發布了劃時代
    的頭像 發表于 07-13 16:48 ?1632次閱讀

    為什么MySQL索引要用B+tree?

    是一種特化的 AVL(平衡二叉),都是在進行插入和刪除操作時通過特定操作保持二叉查找
    發表于 10-30 14:41 ?264次閱讀

    的特點及應用

    比起理解的原理,更重要的是理解的應用場景,因為某些應用場景的需要,
    的頭像 發表于 11-10 11:16 ?769次閱讀
    <b class='flag-5'>紅</b><b class='flag-5'>黑</b><b class='flag-5'>樹</b>的特點及應用
    主站蜘蛛池模板: 成人在线观看免费视频| 亚洲熟伦熟女专区| 收集最新中文国产中文字幕| 亚洲久久少妇中文字幕| 99久久99久久精品免费看子| 国产精品在线手机视频| 免费看欧美一级特黄a大片| 武汉美女洗澡| 99综合之综合久久伊人| 久99久热只有精品国产99| 天天色天天干天天| WWW国产精品人妻一二三区| 久久偷拍vs国产在线播放| 熟女理发厅| www色小姐| 理论片午午伦夜理片2021| 亚洲人美女肛交真人全程| 国产精品高潮AV久久无码| 啪啪漫画无遮挡全彩h同人| 2023极品少妇XXXO露脸| 精品美女国产互换人妻| 無码一区中文字幕少妇熟女网站| chinese学生gv video| 久久偷拍人| 亚洲视频在线观| 果冻传媒完整免费网站在线观看| 天天槽任我槽免费| 港台三级大全| 色欲AV亚洲午夜精品无码| 成人免费公开视频| 日本十八禁无遮无挡漫画| xxx日本黄色| 琪琪电影午夜理论片YY6080| 99热久久这里只精品国产WWW| 久久怡红院国产精品| 印度性hd18| 老阿姨才是最有味的一区二区| 在线观看免费av网| 伦理片飘花免费影院| 91国在线啪精品一区| 免费在线视频成人|