golang實現二叉查找樹

為簡單起見,鍵值均為整型。

定義接口(tree.go):

type Tree interface {
    Put(k, v int)  //新增或修改
    Get(k int) int //查詢
    Delete(k int)  //刪除
    Size() int     //樹的大小
    Min() int      //最小鍵
    DeleteMin()    //刪除最小鍵
}

二叉查找樹(binary_tree.go):

//二叉查找樹
type BinaryTree struct {
    root *node
    n    int
}
 
//創(chuàng)建節(jié)點
func newNode(k, v int) *node {
    return &node{k: k, v: v, sz: 1}
}
 
//創(chuàng)建二叉查找樹
func NewBinaryTree() *BinaryTree {
    return &BinaryTree{}
}
 
//增加或修改
func (bt *BinaryTree) Put(k, v int) {
    bt.root, _ = put(bt.root, k, v)
}
 
//查找
func (bt *BinaryTree) Get(k int) int {
    return get(bt.root, k)
}
 
//樹的大小
func (bt *BinaryTree) Size() int {
    return size(bt.root)
}
 
//選出最小鍵
func (bt *BinaryTree) Min() int {
    return min(bt.root).k
}
 
//刪除最小鍵
func (bt *BinaryTree) DeleteMin() {
    bt.root = deleteMin(bt.root)
}
 
//刪除
func (bt *BinaryTree) Delete(k int) {
    bt.root = delete(bt.root, k)
}

節(jié)點(node.go):

//節(jié)點
type node struct {
    k, v, sz    int   //鍵拣帽,值,大小
    left, right *node //左右子節(jié)點
}

//在以nd為根節(jié)點的樹下增加或修改一個節(jié)點
//如果創(chuàng)建了新節(jié)點驹闰,第二個參數返回true芹关,
//如果只是修改,第二個參數返回false
func put(nd *node, k, v int) (*node, bool) {
    if nd == nil {
        return newNode(k, v), true
    }
    hasNew := false //檢測是否創(chuàng)建了新節(jié)點
    if k < nd.k {
        nd.left, hasNew = put(nd.left, k, v)
    } else if k > nd.k {
        nd.right, hasNew = put(nd.right, k, v)
    } else {
        nd.v = v //僅修改呜呐,不會增加增加節(jié)點就斤,就不更新節(jié)點大小
    }
    if hasNew { //如果創(chuàng)建了新節(jié)點就更新樹的大小
        updateSize(nd)
    }
    return nd, hasNew
}
 
//在以nd為根節(jié)點的樹中獲取鍵為k的值
func get(nd *node, k int) int {
    if nd == nil {
        return -1
    }
    if k < nd.k {
        return get(nd.left, k)
    } else if k > nd.k {
        return get(nd.right, k)
    } else {
        return nd.v
    }
}
 
//獲取以nd為根節(jié)點的樹的大小
func size(nd *node) int {
    if nd == nil {
        return 0
    }
    return nd.sz
}
 
//更新以nd為根節(jié)點的樹的大小
func updateSize(nd *node) {
    if nd == nil {
        return
    }
    nd.sz = size(nd.left) + size(nd.right) + 1
}
 
//選出以nd為根節(jié)點的樹的最小鍵節(jié)點
func min(nd *node) *node {
    if nd == nil {
        return nil
    }
    if nd.left != nil {
        return min(nd.left)
    }
    return nd
}
 
//刪除以nd為根節(jié)點的樹的最小鍵節(jié)點
//返回被刪除的節(jié)點
func deleteMin(nd *node) *node {
    if nd == nil {
        return nil
    }
    if nd.left == nil { //找到最小節(jié)點
        nd = nd.right //用右子節(jié)點代替自己
    } else { //還有更小的
        nd.left = deleteMin(nd.left)
    }
    updateSize(nd)
    return nd
}
 
//刪除以nd為根節(jié)點的樹并且鍵為k的節(jié)點
func delete(nd *node, k int) *node {
    if nd == nil {
        return nil
    }
    if k < nd.k {
        nd.left = delete(nd.left, k)
    } else if k > nd.k {
        nd.right = delete(nd.right, k)
    } else { //命中要刪除的節(jié)點
        //只有一個或零個子節(jié)點
        if nd.right == nil {
            return nd.left
        }
        if nd.left == nil {
            return nd.right
        }
        //同時具有兩個子節(jié)點
        //先找出大于本節(jié)點的最小節(jié)點作為后繼節(jié)點
        t := nd
        nd.k = min(t.right).k
        //刪除
        deleteMin(t.right)
        //用后繼節(jié)點代替本節(jié)點
        nd.left = t.left
    }
    updateSize(nd)
    return nd
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市蘑辑,隨后出現的幾起案子洋机,更是在濱河造成了極大的恐慌,老刑警劉巖洋魂,帶你破解...
    沈念sama閱讀 222,627評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件绷旗,死亡現場離奇詭異喜鼓,居然都是意外死亡,警方通過查閱死者的電腦和手機衔肢,發(fā)現死者居然都...
    沈念sama閱讀 95,180評論 3 399
  • 文/潘曉璐 我一進店門庄岖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人角骤,你說我怎么就攤上這事隅忿。” “怎么了邦尊?”我有些...
    開封第一講書人閱讀 169,346評論 0 362
  • 文/不壞的土叔 我叫張陵背桐,是天一觀的道長。 經常有香客問我蝉揍,道長链峭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,097評論 1 300
  • 正文 為了忘掉前任又沾,我火速辦了婚禮弊仪,結果婚禮上,老公的妹妹穿的比我還像新娘杖刷。我一直安慰自己励饵,他們只是感情好,可當我...
    茶點故事閱讀 69,100評論 6 398
  • 文/花漫 我一把揭開白布挺勿。 她就那樣靜靜地躺著曲横,像睡著了一般。 火紅的嫁衣襯著肌膚如雪不瓶。 梳的紋絲不亂的頭發(fā)上禾嫉,一...
    開封第一講書人閱讀 52,696評論 1 312
  • 那天,我揣著相機與錄音蚊丐,去河邊找鬼熙参。 笑死,一個胖子當著我的面吹牛麦备,可吹牛的內容都是我干的孽椰。 我是一名探鬼主播,決...
    沈念sama閱讀 41,165評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼凛篙,長吁一口氣:“原來是場噩夢啊……” “哼黍匾!你這毒婦竟也來了?” 一聲冷哼從身側響起呛梆,我...
    開封第一講書人閱讀 40,108評論 0 277
  • 序言:老撾萬榮一對情侶失蹤锐涯,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后填物,有當地人在樹林里發(fā)現了一具尸體纹腌,經...
    沈念sama閱讀 46,646評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡霎终,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,709評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了升薯。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片莱褒。...
    茶點故事閱讀 40,861評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖涎劈,靈堂內的尸體忽然破棺而出广凸,到底是詐尸還是另有隱情,我是刑警寧澤蛛枚,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布炮障,位于F島的核電站,受9級特大地震影響坤候,放射性物質發(fā)生泄漏。R本人自食惡果不足惜企蹭,卻給世界環(huán)境...
    茶點故事閱讀 42,196評論 3 336
  • 文/蒙蒙 一白筹、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧谅摄,春花似錦徒河、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至闽寡,卻和暖如春代兵,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背爷狈。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評論 1 274
  • 我被黑心中介騙來泰國打工植影, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人涎永。 一個月前我還...
    沈念sama閱讀 49,287評論 3 379
  • 正文 我出身青樓思币,卻偏偏與公主長得像,于是被迫代替她去往敵國和親羡微。 傳聞我的和親對象是個殘疾皇子谷饿,可洞房花燭夜當晚...
    茶點故事閱讀 45,860評論 2 361

推薦閱讀更多精彩內容