国产chinesehdxxxx老太婆,办公室玩弄爆乳女秘hd,扒开腿狂躁女人爽出白浆 ,丁香婷婷激情俺也去俺来也,ww国产内射精品后入国产

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何使用 go 實(shí)現(xiàn)紅黑樹(shù)

Linux愛(ài)好者 ? 來(lái)源:Linux愛(ài)好者 ? 作者:Linux愛(ài)好者 ? 2022-03-21 11:54 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

本文介紹了使用 go 實(shí)現(xiàn)紅黑樹(shù)。

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

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

二叉樹(shù)的遍歷方式

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

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

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

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

二叉搜索樹(shù)有哪些應(yīng)用?

既然是搜索樹(shù),那么它肯定就是用在查找上。我們來(lái)分析下它的查找時(shí)間復(fù)雜度:

先來(lái)看下面兩顆二叉搜索樹(shù):

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

查找時(shí)間復(fù)雜度其實(shí)就是樹(shù)的深度。

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

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

那么為什么會(huì)出現(xiàn)退化成鏈表的情況(圖一)呢?我們?cè)撛趺刺幚聿挪粫?huì)變成鏈表呢(怎么解決)?

當(dāng)插入的節(jié)點(diǎn)數(shù)值從小到大時(shí),則就會(huì)出現(xiàn)二叉樹(shù)退化成鏈表的情況,那么有另一種樹(shù)可以解決這種情況,就是平衡二叉樹(shù)(AVL樹(shù))。

AVL樹(shù)是一種追求極致平衡的二叉搜索樹(shù),即將樹(shù)調(diào)整到最優(yōu)的情況,由于這種樹(shù)結(jié)構(gòu)比較苛刻、旋轉(zhuǎn)也比較多,這里就不重點(diǎn)展開(kāi)講。

紅黑樹(shù)

紅黑樹(shù)的由來(lái)

今天需要重點(diǎn)講的是紅黑樹(shù)。紅黑樹(shù)的底層數(shù)據(jù)結(jié)構(gòu)其實(shí)就是二叉查找樹(shù),也就是說(shuō)紅黑樹(shù)是一顆特殊的二叉查找樹(shù),也叫自平衡二叉查找樹(shù)

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

紅黑樹(shù)的演進(jìn)過(guò)程

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

紅黑色講解

通過(guò)上面的例子以及兩個(gè)圖,我們發(fā)現(xiàn)二叉樹(shù)的結(jié)構(gòu)就決定了其搜索的效率及性能,那么我們需要怎么樣才讓二叉樹(shù)達(dá)到優(yōu)化的效果呢?

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

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

紅黑樹(shù)的性質(zhì):

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

一定沒(méi)有連在一起的紅色節(jié)點(diǎn)

根節(jié)點(diǎn)(第一個(gè)節(jié)點(diǎn))是黑色 root

每個(gè)紅色節(jié)點(diǎn)的兩個(gè)字節(jié)點(diǎn)都是黑色

葉子結(jié)點(diǎn)都是黑色(上圖中其實(shí)還有為null的葉子結(jié)點(diǎn)沒(méi)有畫出來(lái)),如下圖所示:

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

根據(jù)以上性質(zhì)或者說(shuō)滿足了以上性質(zhì)的樹(shù),就可以達(dá)到近似平衡了。

怎么判斷一個(gè)節(jié)點(diǎn)是否為根結(jié)點(diǎn)?

沒(méi)有父節(jié)點(diǎn)

入度為0的節(jié)點(diǎn)

紅黑樹(shù)變換規(guī)則

要滿足這些性質(zhì),需要對(duì)樹(shù)做什么操作呢?

為了紅黑可以滿足這些性質(zhì),因此出現(xiàn)了旋轉(zhuǎn),那么紅黑樹(shù)有幾種變換規(guī)則呢?

有三種變換規(guī)則:

變色:紅變黑 黑變紅

左旋轉(zhuǎn)

右旋轉(zhuǎn)

左旋轉(zhuǎn)示例:

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

旋轉(zhuǎn)和顏色變換規(guī)則:所有插入的點(diǎn)默認(rèn)為紅色; 1. 變顏色的情況:如果插入的節(jié)點(diǎn)的父節(jié)點(diǎn)和叔叔節(jié)點(diǎn)為紅色,則:1)把父節(jié)點(diǎn)和叔叔節(jié)點(diǎn)設(shè)為黑色;2)把爺爺(祖父)節(jié)點(diǎn)設(shè)為紅色;3)把指針定位到爺爺節(jié)點(diǎn)作為當(dāng)前需要操作的節(jié)點(diǎn),再根據(jù)變換規(guī)則來(lái)進(jìn)行判斷操作。2. 左旋:如果當(dāng)前父節(jié)點(diǎn)是紅色,叔叔節(jié)點(diǎn)是黑色,而且當(dāng)前的節(jié)點(diǎn)是右子樹(shù)時(shí),則需要以父節(jié)點(diǎn)作為左旋轉(zhuǎn)。3. 右旋:當(dāng)前父節(jié)點(diǎn)是紅色,叔叔節(jié)點(diǎn)是黑色,且當(dāng)前的節(jié)點(diǎn)是左子樹(shù)時(shí),則:1)把父節(jié)點(diǎn)變?yōu)楹谏?)把爺爺節(jié)點(diǎn)變?yōu)榧t色;3)以父節(jié)點(diǎn)右旋轉(zhuǎn)。

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

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

step1: 插入6節(jié)點(diǎn)后如下圖,它的父節(jié)點(diǎn)和叔叔節(jié)點(diǎn)均是紅色,則需要根據(jù)變換規(guī)則來(lái)操作,到step2了。

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

step2: 根據(jù)變換規(guī)則,需要將插入節(jié)點(diǎn)的父節(jié)點(diǎn)和叔叔節(jié)點(diǎn)均變?yōu)楹谏?,爺爺?jié)點(diǎn)變?yōu)榧t色,然后將指針定位到爺爺節(jié)點(diǎn)(藍(lán)色圈)。將指針定位到爺爺節(jié)點(diǎn)(12)后,此時(shí)做為當(dāng)前需要操作的節(jié)點(diǎn),再根據(jù)變換規(guī)則來(lái)判斷,可以看到下圖的當(dāng)前節(jié)點(diǎn)(12)的叔叔節(jié)點(diǎn)是黑色的,則不能用變顏色規(guī)則的情況了,進(jìn)行step3,此時(shí)需要進(jìn)行左旋或右旋了。

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

step3: 根據(jù)上圖情況可以知道此時(shí)是符合左旋規(guī)則的:當(dāng)前節(jié)點(diǎn)(12)的父節(jié)點(diǎn)(5)是紅色,叔叔節(jié)點(diǎn)(3)是黑色,而且當(dāng)前的節(jié)點(diǎn)是右子樹(shù)。接下來(lái)需要進(jìn)行左旋變換(三步走):

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

step4:左旋變換后,可以看到當(dāng)前節(jié)點(diǎn)(5)的父節(jié)點(diǎn)(12)為紅色,叔叔節(jié)點(diǎn)(30)為黑色,而且當(dāng)前節(jié)點(diǎn)為左子樹(shù),符合右旋的規(guī)則。接下來(lái)就是進(jìn)行右旋的變換操作了:1)把父節(jié)點(diǎn)(12)變?yōu)楹谏?)把爺爺節(jié)點(diǎn)(29)變?yōu)榧t色;3)以父節(jié)點(diǎn)(12)右旋轉(zhuǎn)

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

小結(jié)

到這里,可以看到經(jīng)過(guò)多次旋轉(zhuǎn)后,這棵樹(shù)是符合紅黑色的性質(zhì)。

Golang代碼實(shí)現(xiàn)紅黑樹(shù)

直接上代碼,如下:

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{
//默認(rèn)添加紅節(jié)點(diǎn)
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
///左旋轉(zhuǎn)/
//T1x--------->nodeT3
////
//T2T3T1T2
func(n*Node)leftRotate()*Node{
//左旋轉(zhuǎn)
retNode:=n.right
n.right=retNode.left

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

returnretNode
}

//nodex
///右旋轉(zhuǎn)/
//xT2------->ynode
////
//yT1T1T2
func(n*Node)rightRotate()*Node{
//右旋轉(zhuǎn)
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
}

//維護(hù)紅黑樹(shù)
func(n*Node)updateRedBlackTree(isAddint)*Node{
//isAdd=0說(shuō)明沒(méi)有新節(jié)點(diǎn),無(wú)需維護(hù)
ifisAdd==0{
returnn
}

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

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

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

returnn
}

//遞歸寫法:向樹(shù)的root節(jié)點(diǎn)中插入key,val
//返回1,代表加了節(jié)點(diǎn)
//返回0,代表沒(méi)有添加新節(jié)點(diǎn),只更新key對(duì)應(yīng)的value值
func(n*Node)add(key,valint)(int,*Node){
ifn==nil{//默認(rèn)插入紅色節(jié)點(diǎn)
return1,NewNode(key,val)
}

isAdd:=0
ifkeyn.key{
isAdd,n.right=n.right.add(key,val)
}else{
//對(duì)value值更新,節(jié)點(diǎn)數(shù)量不增加,isAdd=0
n.value=val
}

//維護(hù)紅黑樹(shù)
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//根節(jié)點(diǎn)為黑色節(jié)點(diǎn)
}

//前序遍歷打印出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)
}


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

測(cè)試輸出結(jié)果如下:

datasource:[1779185060]
redBlackTree:-2.136μs
[[77false][11true][00false][66false][55true][99false][88true]]
節(jié)點(diǎn)數(shù)量:7

總結(jié)

紅黑樹(shù)是保持近似平衡的二叉樹(shù),從另一種角度上來(lái)說(shuō)紅黑樹(shù)不是平衡二叉樹(shù),它的最大高度為2*logn。

二分搜索樹(shù),AVL樹(shù),紅黑樹(shù)對(duì)比:1. 對(duì)于完全隨機(jī)的數(shù)據(jù)源,普通二分搜索樹(shù)很好用,缺陷是在極端情況下容易退化成鏈表 2. 對(duì)于查詢較多的使用情況,AVL樹(shù)很好用,因?yàn)樗母叨纫恢北3謍=logn 3. 紅黑樹(shù)犧牲了平衡性,即h=2*logn,但在添加和刪除操作中,紅黑樹(shù)比AVL樹(shù)有優(yōu)勢(shì) 4. 綜合增刪改查所有操作,紅黑樹(shù)的統(tǒng)計(jì)性能更優(yōu)

原文標(biāo)題:二叉樹(shù)、紅黑樹(shù)以及Golang實(shí)現(xiàn)紅黑樹(shù)

文章出處:【微信公眾號(hào):Linux愛(ài)好者】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

審核編輯:彭菁

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4900

    瀏覽量

    70786
  • 數(shù)據(jù)源
    +關(guān)注

    關(guān)注

    1

    文章

    65

    瀏覽量

    9924
  • 二叉樹(shù)
    +關(guān)注

    關(guān)注

    0

    文章

    74

    瀏覽量

    12644

原文標(biāo)題:二叉樹(shù)、紅黑樹(shù)以及Golang實(shí)現(xiàn)紅黑樹(shù)

文章出處:【微信號(hào):LinuxHub,微信公眾號(hào):Linux愛(ài)好者】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    Go語(yǔ)言實(shí)現(xiàn)敏感詞檢測(cè)(前綴樹(shù)

    大家都知道游戲文字、文章等一些風(fēng)控場(chǎng)景都實(shí)現(xiàn)了敏感詞檢測(cè),一些敏感詞會(huì)被屏蔽掉或者文章無(wú)法發(fā)布。今天我就分享用Go實(shí)現(xiàn)敏感詞前綴樹(shù)來(lái)達(dá)到文本的敏感詞檢測(cè),讓我們一探究竟!
    發(fā)表于 10-31 10:22 ?1448次閱讀

    驗(yàn)功放時(shí)將輸出端柱短路,為什么會(huì)燒功放

    驗(yàn)功放時(shí)將輸出端柱短路,為什么會(huì)燒功放
    發(fā)表于 08-26 18:54

    什么是“樹(shù)”看了就知道

    今天我們要說(shuō)的樹(shù)就是就是一棵非嚴(yán)格均衡的二叉樹(shù),均衡二叉樹(shù)又是在二叉搜索樹(shù)的基礎(chǔ)上增加了自動(dòng)
    發(fā)表于 10-27 17:00

    Linux下一種高性能定時(shí)器池的實(shí)現(xiàn)

    提出Linux用戶空間下的一種高性能定時(shí)器池的實(shí)現(xiàn)方法。主要基于時(shí)間輪、樹(shù)及Linux內(nèi)核提供了一種利于管理的定時(shí)器句柄Timerfd。結(jié)合
    發(fā)表于 09-25 14:57 ?25次下載

    一文詳解樹(shù)

    界應(yīng)用很廣泛,比如 Java 中的 TreeMap,JDK 1.8 中的 HashMap、C++ STL 中的 map 均是基于樹(shù)結(jié)構(gòu)實(shí)現(xiàn)的??紤]到
    的頭像 發(fā)表于 02-02 17:25 ?4459次閱讀
    一文詳解<b class='flag-5'>紅</b><b class='flag-5'>黑</b><b class='flag-5'>樹(shù)</b>

    詳解電源二叉樹(shù)到底是什么

    作為數(shù)據(jù)結(jié)構(gòu)的基礎(chǔ),樹(shù)分很多種,像 AVL 樹(shù)、樹(shù)、二叉搜索樹(shù)....今天我想分享的是關(guān)于二
    的頭像 發(fā)表于 06-06 15:05 ?1.1w次閱讀
    詳解電源二叉<b class='flag-5'>樹(shù)</b>到底是什么

    魔3和鯊2買哪個(gè)好

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

    鯊2和魔3哪個(gè)好

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

    魔Mars和鯊Helo哪個(gè)最好

    在18年的圈里,游戲手機(jī)燃起了很大的熱點(diǎn),尤其是鯊和魔更是打動(dòng)很多手游愛(ài)好者,進(jìn)化后的魔Mars和鯊Helo更是棋逢對(duì)手,如今令人期待的
    的頭像 發(fā)表于 07-11 11:43 ?3827次閱讀

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

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

    Go并發(fā)模型的實(shí)現(xiàn)原理

    Go語(yǔ)言是為并發(fā)而生的語(yǔ)言,Go語(yǔ)言是為數(shù)不多的在語(yǔ)言層面實(shí)現(xiàn)并發(fā)的語(yǔ)言;也正是Go語(yǔ)言的并發(fā)特性,吸引了全球無(wú)數(shù)的開(kāi)發(fā)者。
    的頭像 發(fā)表于 04-15 08:49 ?1637次閱讀

    樹(shù)是如何模擬2-3 B樹(shù)的操作邏輯的

    大家都聽(tīng)說(shuō)過(guò)樹(shù),也都知道樹(shù)很厲害,是計(jì)算機(jī)里面評(píng)價(jià)非常高的數(shù)據(jù)結(jié)構(gòu)。但是每當(dāng)想學(xué)習(xí)
    的頭像 發(fā)表于 08-30 10:22 ?1193次閱讀

    樹(shù)Unitree Go2四足機(jī)器人:智能科技新選擇

    7月12日,宇樹(shù)推出了備受矚目的Unitree Go2四足機(jī)器人,售價(jià)從9997元起。這款產(chǎn)品將徹底改變以往消費(fèi)級(jí)四足機(jī)器人的市場(chǎng)格局,并引領(lǐng)整個(gè)行業(yè)的變革。早在2021年6月,宇樹(shù)就發(fā)布了劃時(shí)代
    的頭像 發(fā)表于 07-13 16:48 ?2517次閱讀

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

    樹(shù)是一種特化的 AVL樹(shù)(平衡二叉樹(shù)),都是在進(jìn)行插入和刪除操作時(shí)通過(guò)特定操作保持二叉查找樹(shù)
    發(fā)表于 10-30 14:41 ?463次閱讀

    樹(shù)的特點(diǎn)及應(yīng)用

    比起理解樹(shù)的原理,更重要的是理解樹(shù)的應(yīng)用場(chǎng)景,因?yàn)槟承?yīng)用場(chǎng)景的需要,
    的頭像 發(fā)表于 11-10 11:16 ?1144次閱讀
    <b class='flag-5'>紅</b><b class='flag-5'>黑</b><b class='flag-5'>樹(shù)</b>的特點(diǎn)及應(yīng)用