在上篇整理了二叉樹的相對基礎的資訊深入理解資料結構–二叉樹(基礎篇)
接下來深入講解二叉樹的進階內容
二叉查詢樹
二叉查詢樹(Binary Search Tree),顧名思義,是用來查詢資料的。它在二叉樹的基礎上,增加了幾個規則:
- 如果左子樹不為空,則左子樹上所有節點的值均小於根節點的值。
- 如果右子樹不為空,則右子樹上所有節點的值均大於根節點的值。
- 左、右子樹也都是二叉查詢樹。
下圖就是一顆標準的二叉查詢樹:
二叉樹的程式碼結構用go的結構體來實現如下:
type binaryTree struct {
value int
leftNode *binaryTree
rightNode *binaryTree
}
二叉查詢樹有三個操作:查詢、插入和刪除
二叉樹的查詢
假設我們要查詢的值是4,查詢過程如下:
- 訪問根節點6,發現4<6
- 訪問根節點6的左孩子節點3,發現4>3
- 訪問節點3的右孩子節點4,發現正是要查詢的節點
對於一個節點分佈相對平衡的二叉查詢樹,如果節點總數是n,那麼查詢節點的時間複雜度就是O(logn),和樹的深度成正比
實現程式碼如下:
//節點查詢
func findNode(num int,tree *binaryTree) bool{
targetNode := tree
for targetNode != nil{
if targetNode.value == num {
return true
}else if targetNode.value > num {
targetNode = targetNode.leftNode
}else {
targetNode = targetNode.rightNode
}
}
return false
}
二叉樹的插入
二叉樹的插入遍歷過程與查詢類似,這裡就直接寫程式碼實現
//節點插入
func insertNode(tree *binaryTree,node *binaryTree) *binaryTree {
if tree.value == 0 {
return node
}
if tree.value == node.value {
return tree
}else if tree.value > node.value {
//往左子樹走,為空則直接插入節點
if tree.leftNode == nil {
tree.leftNode = node
}else {
tree.leftNode = insertNode(tree.leftNode,node)
}
}else {
//往右子樹走,為空則直接插入節點
if tree.rightNode == nil {
tree.rightNode = node
}else {
tree.rightNode = insertNode(tree.rightNode,node)
}
}
return tree
}
二叉樹的刪除
相對查詢和插入,二叉樹的刪除過程相對複雜一些,程式碼實現上也有對應的邏輯
二叉樹的刪除操作,可分為三種情況:
情況1,待刪除的節點沒有子節點
上圖中,待刪除的節點12是葉子節點,沒有孩子,因此直接刪除即可
情況2,待刪除的節點有一個孩子
上圖中,待刪除的節點13只有左孩子,於是我們讓左孩子節點11取代被刪除的節點,節點11以下的節點關係無須變動
情況3,待刪除的節點有兩個孩子
上圖中,待刪除的節點5有兩個孩子,這種情況比較複雜。需要選擇與待刪除節點最接近的節點來取代它。
上面的例子中,節點3僅小於節點5,節點6僅大於節點5.兩者都是合適的選擇。但習慣上我們選擇僅大於待刪除節點的節點,也就是用節點6來取代它。
被選中的節點6,僅大於節點5,因此一定沒有左孩子。所以我們按照情況1或情況2的方式,刪除多餘的節點6。
程式碼實現如下,實現上相對複雜一點,需要運用遞迴的方式去處理:
//刪除節點
func deleteNode(num int,tree *binaryTree) *binaryTree{
//先檢視刪除的值是否存在樹當中
find := findNode(num,tree)
if find {
//配置到節點值,執行刪除操作
if tree.value == num {
//刪除的節點無左右節點
if tree.leftNode == nil && tree.rightNode == nil {
tree = &binaryTree{}
}else if tree.leftNode == nil && tree.rightNode != nil {
//左節點為空,右節點不為空
tree = tree.rightNode
}else if tree.rightNode == nil && tree.leftNode != nil {
//右節點為空,左節點不為空
tree = tree.leftNode
}else{
//節點左右節點都存在
tree = replaceNode(tree)
}
}else if tree.value > num {
tree.leftNode = deleteNode(num,tree.leftNode)
}else {
tree.rightNode = deleteNode(num,tree.rightNode)
}
}
return tree
}
//替換刪除節點
func replaceNode(tree *binaryTree) *binaryTree{
//刪除的節點無左右節點
if tree.leftNode == nil && tree.rightNode == nil {
tree = &binaryTree{}
}else if tree.leftNode == nil && tree.rightNode != nil {
//左節點為空,右節點不為空
tree = tree.rightNode
}else if tree.rightNode == nil && tree.leftNode != nil {
//右節點為空,左節點不為空
tree = tree.leftNode
}else{
//節點左右節點都存在,則從右子樹查詢節點替代父節點
//若右節點下沒有左右節點,則直接用右節點的值替換,並刪除右節點
if tree.rightNode.leftNode == nil && tree.rightNode.rightNode == nil {
tree.value = tree.rightNode.value
tree.rightNode = &binaryTree{}
}else if tree.rightNode.leftNode == nil && tree.rightNode.rightNode != nil {
//若右節點下左節點為空,右節點不為空,則右節點的值替換,並將右節點的右節點替換過來
tree.value = tree.rightNode.value
tree.rightNode = tree.rightNode.rightNode
}else{
//若右節點的左節點不為空
tree.value = tree.rightNode.leftNode.value
tree.rightNode.leftNode = replaceNode(tree.rightNode.leftNode)
}
}
return tree
}
實現二叉查詢樹的完整程式碼如下,二叉查詢樹的中序遍歷可獲取到已排序完成的節點,所以這裡用中序遍歷來判斷是否執行成功
package main
import "fmt"
type binaryTree struct {
value int
leftNode *binaryTree
rightNode *binaryTree
}
func main(){
var numArr = []int{10,11,4,2,8,1,3,6,9,5,7}
tree := createBinarySearchTree(numArr)
find := findNode(9,tree)
fmt.Print(find)
tree = deleteNode(4,tree)
node := &binaryTree{13,nil,nil}
tree = insertNode(tree,node)
node = &binaryTree{1,nil,nil}
var middle []int
middle = middleForeach(*tree,middle)
fmt.Println(middle)
}
//建立平衡二叉樹
func createBinarySearchTree(nums []int) *binaryTree{
tree := new(binaryTree)
for index := range nums{
node := &binaryTree{nums[index],nil,nil}
tree = insertNode(tree,node)
}
return tree
}
//刪除節點
func deleteNode(num int,tree *binaryTree) *binaryTree{
//先檢視刪除的值是否存在樹當中
find := findNode(num,tree)
if find {
//配置到節點值,執行刪除操作
if tree.value == num {
//刪除的節點無左右節點
if tree.leftNode == nil && tree.rightNode == nil {
tree = &binaryTree{}
}else if tree.leftNode == nil && tree.rightNode != nil {
//左節點為空,右節點不為空
tree = tree.rightNode
}else if tree.rightNode == nil && tree.leftNode != nil {
//右節點為空,左節點不為空
tree = tree.leftNode
}else{
//節點左右節點都存在
tree = replaceNode(tree)
}
}else if tree.value > num {
tree.leftNode = deleteNode(num,tree.leftNode)
}else {
tree.rightNode = deleteNode(num,tree.rightNode)
}
}
return tree
}
//替換刪除節點
func replaceNode(tree *binaryTree) *binaryTree{
//刪除的節點無左右節點
if tree.leftNode == nil && tree.rightNode == nil {
tree = &binaryTree{}
}else if tree.leftNode == nil && tree.rightNode != nil {
//左節點為空,右節點不為空
tree = tree.rightNode
}else if tree.rightNode == nil && tree.leftNode != nil {
//右節點為空,左節點不為空
tree = tree.leftNode
}else{
//節點左右節點都存在,則從右子樹查詢節點替代父節點
//若右節點下沒有左右節點,則直接用右節點的值替換,並刪除右節點
if tree.rightNode.leftNode == nil && tree.rightNode.rightNode == nil {
tree.value = tree.rightNode.value
tree.rightNode = &binaryTree{}
}else if tree.rightNode.leftNode == nil && tree.rightNode.rightNode != nil {
//若右節點下左節點為空,右節點不為空,則右節點的值替換,並將右節點的右節點替換過來
tree.value = tree.rightNode.value
tree.rightNode = tree.rightNode.rightNode
}else{
//若右節點的左節點不為空
tree.value = tree.rightNode.leftNode.value
tree.rightNode.leftNode = replaceNode(tree.rightNode.leftNode)
}
}
return tree
}
//節點查詢
func findNode(num int,tree *binaryTree) bool{
targetNode := tree
for targetNode != nil{
if targetNode.value == num {
return true
}else if targetNode.value > num {
targetNode = targetNode.leftNode
}else {
targetNode = targetNode.rightNode
}
}
return false
}
//節點插入
func insertNode(tree *binaryTree,node *binaryTree) *binaryTree {
if tree.value == 0 {
return node
}
if tree.value == node.value {
return tree
}else if tree.value > node.value {
//往左子樹走,為空則直接插入節點
if tree.leftNode == nil {
tree.leftNode = node
}else {
tree.leftNode = insertNode(tree.leftNode,node)
}
}else {
//往右子樹走,為空則直接插入節點
if tree.rightNode == nil {
tree.rightNode = node
}else {
tree.rightNode = insertNode(tree.rightNode,node)
}
}
return tree
}
//中序遍歷
func middleForeach(tree binaryTree,num []int) []int{
var leftNum,rightNum []int
//若存在左節點,遍歷左節點樹
if tree.leftNode != nil {
leftNum = middleForeach(*tree.leftNode,leftNum)
for _,value := range leftNum{
num = append(num,value)
}
}
//先遍歷根節點
if tree.value != 0 {
num = append(num,tree.value)
}
//若存在右節點,遍歷右節點樹
if tree.rightNode != nil {
rightNum = middleForeach(*tree.rightNode,rightNum)
for _,value := range rightNum{
num = append(num,value)
}
}
return num
}
二叉樹的缺陷
假設初始的二叉查詢樹只有三個節點,根節點為9,左孩子為8,右孩子為12
接下來我們依次插入如下五個節點:7,6,5,4,3。依照二叉查詢樹的特性,結果會變成什麼樣呢?
雖然這樣一棵樹也符合二叉查詢樹的特性,但是查詢節點的時間複雜度退化成了O(n)
二叉平衡樹
二叉平衡樹是一種特性的二叉查詢樹,也被稱為AVL樹。它在每次插入、刪除節點之後,可以進行“自平衡”,也就是通過一系列調整重新達到平衡狀態。
平衡因子
下圖就是一顆典型的AVL樹,每個節點旁邊都標註了平衡因子
其中節點4的左子樹高度是1,右子樹不存在,所以該節點的平衡因子是1-0=1
其中7的左子樹不存在,右子樹高度是1,所以平衡因子是0-1=-1
所有的葉子節點,不存在左右子樹,所以平衡因子都是0
AVL樹對平衡因子的限制(只能是-1,0,1),保證了任意節點的兩棵樹的高度差都不超過1,這種狀態被稱為高度平衡
以下是對計算樹平衡因子的程式碼實現,首先要計算左右子樹的高度,然後得到平衡因子,還新增了方法用於判斷樹是否達到平衡
//檢查樹是否達到平衡
func (tree binaryTree) isBalance() bool {
if tree.RightNode == nil && tree.LeftNode == nil {
return true
}
//節點的平衡因子
factor := tree.getTreeFactor()
if factor > 1 || factor < -1 {
return false
}
return true
}
//獲取節點的平衡因子
func (tree binaryTree) getTreeFactor() int{
leftFactor,rightFactor := 0,0
if tree.RightNode != nil {
rightFactor = tree.RightNode.getTreeHeight()
}
if tree.LeftNode != nil {
leftFactor = tree.LeftNode.getTreeHeight()
}
factor := float64(leftFactor - rightFactor)
return int(factor)
}
//獲取節點樹高度,深度優先
func (tree binaryTree) getTreeHeight() int{
//節點無
if tree.RightNode == nil && tree.LeftNode == nil {
return 1
}
leftHeight,rightHeight := 1,1
if tree.LeftNode != nil && tree.LeftNode.Value != 0 {
leftHeight = 1 + tree.LeftNode.getTreeHeight()
}
if tree.RightNode != nil && tree.RightNode.Value != 0{
rightHeight = 1 + tree.RightNode.getTreeHeight()
}
//比較左右節點樹高度
height := math.Max(float64(leftHeight),float64(rightHeight))
return int(height)
}
樹平衡調整
當插入節點導致平衡因子被打破,這時候需要對樹進行調整,AVL樹調整可分為4種情況
- 左左局面(LL)
顧名思義,祖父節點A右一個左孩子節點B,而節點B又有一個左孩子節點C。標號1,2,3,4的三角形是各個節點的子樹。
在這種局面下,我們以節點A為軸,進行右旋操作:
- 右右局面(RR)
祖父節點A有一個右孩子節點B,而節點B又有一個右孩子節點C。
在這種局面下,我們以節點A為軸,進行左旋操作。
- 左右局面(LR)
祖父節點A有一個左孩子節點B,而節點B又有一個右孩子節點C。
在這種局面下,我們先以節點B為軸,進行左旋操作。
這樣就轉化成了左左局面。我們繼續以節點A為軸,進行右旋操作。
- 右左局面(RL)
祖父節點A右一個右孩子節點B,而節點B又有一個左孩子節點C。
在這種局面下,我們先以節點B為軸,進行右旋操作。
這樣就轉化成了右右局面。我們繼續以節點A為軸,進行左旋操作。
程式碼實現如下:
//左左局面
func LeftLeftRotate(tree *binaryTree) *binaryTree{
//原節點左節點成為根節點
mainNode := tree.LeftNode
changeNode := &binaryTree{}
//判斷原節點左節點是否存在
if mainNode.RightNode != nil {
changeNode = mainNode.RightNode
}
mainRightNode := tree
mainRightNode.LeftNode = changeNode
//重新整理樹高度
mainRightNode.Height = mainRightNode.getTreeHeight()
mainNode.RightNode = mainRightNode
mainNode.Height = mainNode.getTreeHeight()
return mainNode
}
//右右局面
func RightRightRotate(tree *binaryTree) *binaryTree{
mainNode := tree.RightNode
changeNode := &binaryTree{}
if mainNode.LeftNode != nil {
changeNode = mainNode.LeftNode
}
mainLeftNode := tree
mainLeftNode.RightNode = changeNode
mainLeftNode.Height = mainLeftNode.getTreeHeight()
mainNode.LeftNode = mainLeftNode
mainNode.Height = mainNode.getTreeHeight()
return mainNode
}
//左右局面
func LeftRightRotate(tree *binaryTree) *binaryTree{
mainLeftNode := tree.LeftNode
changeNode := &binaryTree{}
mainNode := mainLeftNode.RightNode
if mainNode.LeftNode != nil {
changeNode = mainNode.LeftNode
}
mainLeftNode.RightNode = changeNode
mainLeftNode.Height = mainLeftNode.getTreeHeight()
mainNode.LeftNode = mainLeftNode
mainNode.Height = mainNode.getTreeHeight()
tree.LeftNode = mainNode
tree = LeftLeftRotate(tree)
return tree
}
//右左局面
func RightLightRotate(tree *binaryTree) *binaryTree{
mainRightNode := tree.RightNode
changeNode := &binaryTree{}
mainNode := mainRightNode.LeftNode
if mainNode.RightNode != nil {
changeNode = mainNode.RightNode
}
mainRightNode.LeftNode = changeNode
mainRightNode.Height = mainRightNode.getTreeHeight()
mainNode.RightNode = mainRightNode
mainNode.Height = mainNode.getTreeHeight()
tree.RightNode = mainNode
tree = RightRightRotate(tree)
return tree
}
二叉平衡樹的插入和刪除
在程式碼實現上,可以複用二叉查詢樹的程式碼邏輯,在二叉查詢樹的基礎上新增邏輯,在節點的插入和刪除後,新增判斷邏輯,判斷二叉平衡樹的平衡是否被破壞,若被破壞則進行相關的調整,過程就不多贅述,直接上完整實現程式碼
package main
import (
"fmt"
"math"
)
type binaryTree struct {
Value int
Height int
LeftNode *binaryTree
RightNode *binaryTree
}
func main(){
var numArr = []int{10,11,4,2,8,1,3,6,9,5,7,12}
tree := createBinaryBalanceTree(numArr)
var middle []int
tree = deleteNode(9,tree)
tree = deleteNode(11,tree)
tree = deleteNode(12,tree)
fmt.Println("\n")
middle := middleForeach(*tree,middle)
fmt.Println(middle,"\n")
}
//獲取節點樹高度,深度優先
func (tree binaryTree) getTreeHeight() int{
//節點無
if tree.RightNode == nil && tree.LeftNode == nil {
return 1
}
leftHeight,rightHeight := 1,1
if tree.LeftNode != nil && tree.LeftNode.Value != 0 {
leftHeight = 1 + tree.LeftNode.getTreeHeight()
}
if tree.RightNode != nil && tree.RightNode.Value != 0{
rightHeight = 1 + tree.RightNode.getTreeHeight()
}
//比較左右節點樹高度
height := math.Max(float64(leftHeight),float64(rightHeight))
return int(height)
}
//檢查樹是否達到平衡
func (tree binaryTree) isBalance() bool {
if tree.RightNode == nil && tree.LeftNode == nil {
return true
}
//節點的平衡因子
factor := tree.getTreeFactor()
if factor > 1 || factor < -1 {
return false
}
return true
}
//獲取節點的平衡因子
func (tree binaryTree) getTreeFactor() int{
leftFactor,rightFactor := 0,0
if tree.RightNode != nil {
rightFactor = tree.RightNode.getTreeHeight()
}
if tree.LeftNode != nil {
leftFactor = tree.LeftNode.getTreeHeight()
}
factor := float64(leftFactor - rightFactor)
return int(factor)
}
//建立二叉平衡樹
func createBinaryBalanceTree(nums []int) *binaryTree{
tree := new(binaryTree)
for index := range nums{
node := &binaryTree{Value: nums[index]}
tree = insertNode(tree,node)
}
return tree
}
//插入節點
func insertNode(tree *binaryTree,node *binaryTree) *binaryTree {
if tree.Value == 0 {
return node
}
if tree.Value == node.Value {
return tree
}else if tree.Value > node.Value {
//往左子樹走,為空則直接插入節點
if tree.LeftNode == nil {
tree.LeftNode = node
}else {
tree.LeftNode = insertNode(tree.LeftNode,node)
}
//節點高度重置
tree.LeftNode.Height = tree.LeftNode.getTreeHeight()
}else {
//往右子樹走,為空則直接插入節點
if tree.RightNode == nil {
tree.RightNode = node
}else {
tree.RightNode = insertNode(tree.RightNode,node)
}
//節點高度重置
tree.RightNode.Height = tree.RightNode.getTreeHeight()
}
//節點高度重置
tree.Height = tree.getTreeHeight()
//節點不平衡
if !tree.isBalance() {
//tree = treeInsertRotateBalance(node,tree)
//左子樹偏大
if tree.getTreeFactor() > 1 {
if node.Value < tree.LeftNode.Value {
tree = LeftLeftRotate(tree)
}else {
tree = LeftRightRotate(tree)
}
}else {
//右子樹偏大
if node.Value > tree.RightNode.Value {
tree = RightRightRotate(tree)
}else {
tree = RightLightRotate(tree)
}
}
}
return tree
}
//刪除節點
func deleteNode(num int,tree *binaryTree) *binaryTree{
//先檢視刪除的值是否存在樹當中
find := findNode(num,tree)
if find {
//配置到節點值,執行刪除操作
if tree.Value == num {
//刪除的節點無左右節點
if tree.LeftNode == nil && tree.RightNode == nil {
tree = &binaryTree{}
}else if tree.LeftNode == nil && tree.RightNode != nil {
//左節點為空,右節點不為空
tree = tree.RightNode
}else if tree.RightNode == nil && tree.LeftNode != nil {
//右節點為空,左節點不為空
tree = tree.LeftNode
}else{
//節點左右節點都存在
tree = replaceNode(tree)
}
}else if tree.Value > num {
tree.LeftNode = deleteNode(num,tree.LeftNode)
}else {
tree.RightNode = deleteNode(num,tree.RightNode)
}
tree.Height = tree.getTreeHeight()
}
if !tree.isBalance() {
if tree.getTreeFactor() > 1 {
if num > tree.Value {
tree = LeftLeftRotate(tree)
}else {
tree = LeftRightRotate(tree)
}
}else {
if num < tree.Value {
tree = RightRightRotate(tree)
}else {
tree = RightLightRotate(tree)
}
}
}
return tree
}
//替換刪除節點
func replaceNode(tree *binaryTree) *binaryTree{
//刪除的節點無左右節點
if tree.LeftNode == nil && tree.RightNode == nil {
tree = &binaryTree{}
}else if tree.LeftNode == nil && tree.RightNode != nil {
//左節點為空,右節點不為空
tree = tree.RightNode
}else if tree.RightNode == nil && tree.LeftNode != nil {
//右節點為空,左節點不為空
tree = tree.LeftNode
}else{
//節點左右節點都存在,則從右子樹查詢節點替代父節點
//若右節點下沒有左右節點,則直接用右節點的值替換,並刪除右節點
if tree.RightNode.LeftNode == nil && tree.RightNode.RightNode == nil {
tree.Value = tree.RightNode.Value
tree.RightNode = &binaryTree{}
}else if tree.RightNode.LeftNode == nil && tree.RightNode.RightNode != nil {
//若右節點下左節點為空,右節點不為空,則右節點的值替換,並將右節點的右節點替換過來
tree.Value = tree.RightNode.Value
tree.RightNode = tree.RightNode.RightNode
}else{
//若右節點的左節點不為空
tree.Value = tree.RightNode.LeftNode.Value
tree.RightNode.LeftNode = replaceNode(tree.RightNode.LeftNode)
}
}
return tree
}
//左左局面
func LeftLeftRotate(tree *binaryTree) *binaryTree{
//原節點左節點成為根節點
mainNode := tree.LeftNode
changeNode := &binaryTree{}
//判斷原節點左節點是否存在
if mainNode.RightNode != nil {
changeNode = mainNode.RightNode
}
mainRightNode := tree
mainRightNode.LeftNode = changeNode
//重新整理樹高度
mainRightNode.Height = mainRightNode.getTreeHeight()
mainNode.RightNode = mainRightNode
mainNode.Height = mainNode.getTreeHeight()
return mainNode
}
//右右局面
func RightRightRotate(tree *binaryTree) *binaryTree{
mainNode := tree.RightNode
changeNode := &binaryTree{}
if mainNode.LeftNode != nil {
changeNode = mainNode.LeftNode
}
mainLeftNode := tree
mainLeftNode.RightNode = changeNode
mainLeftNode.Height = mainLeftNode.getTreeHeight()
mainNode.LeftNode = mainLeftNode
mainNode.Height = mainNode.getTreeHeight()
return mainNode
}
//左右局面
func LeftRightRotate(tree *binaryTree) *binaryTree{
mainLeftNode := tree.LeftNode
changeNode := &binaryTree{}
mainNode := mainLeftNode.RightNode
if mainNode.LeftNode != nil {
changeNode = mainNode.LeftNode
}
mainLeftNode.RightNode = changeNode
mainLeftNode.Height = mainLeftNode.getTreeHeight()
mainNode.LeftNode = mainLeftNode
mainNode.Height = mainNode.getTreeHeight()
tree.LeftNode = mainNode
tree = LeftLeftRotate(tree)
return tree
}
//右左局面
func RightLightRotate(tree *binaryTree) *binaryTree{
mainRightNode := tree.RightNode
changeNode := &binaryTree{}
mainNode := mainRightNode.LeftNode
if mainNode.RightNode != nil {
changeNode = mainNode.RightNode
}
mainRightNode.LeftNode = changeNode
mainRightNode.Height = mainRightNode.getTreeHeight()
mainNode.RightNode = mainRightNode
mainNode.Height = mainNode.getTreeHeight()
tree.RightNode = mainNode
tree = RightRightRotate(tree)
return tree
}
//節點查詢
func findNode(num int,tree *binaryTree) bool{
targetNode := tree
for targetNode != nil{
if targetNode.Value == num {
return true
}else if targetNode.Value > num {
targetNode = targetNode.LeftNode
}else {
targetNode = targetNode.RightNode
}
}
return false
}
//中序遍歷
func middleForeach(tree binaryTree,num []int) []int{
var leftNum,rightNum []int
//若存在左節點,遍歷左節點樹
if tree.LeftNode != nil {
leftNum = middleForeach(*tree.LeftNode,leftNum)
for _,value := range leftNum{
num = append(num,value)
}
}
//先遍歷根節點
if tree.Value != 0 {
num = append(num,tree.Value)
}
//若存在右節點,遍歷右節點樹
if tree.RightNode != nil {
rightNum = middleForeach(*tree.RightNode,rightNum)
for _,value := range rightNum{
num = append(num,value)
}
}
return num
}
程式碼實現上相對有點複雜,在開始編寫的時候還是有點難度,但是完成後發現給自己帶來了特別大的成就感,或許這也是寫程式碼的樂趣吧。後續會繼續學習,爭取把紅黑樹也實現了。
本作品採用《CC 協議》,轉載必須註明作者和本文連結