MaxHeap / MinHeap / PriorityQueue

復(fù)盤:

Max Heap 最大堆實(shí)現(xiàn)

優(yōu)化了shiftDown的判斷減少了重復(fù)代碼 , 在遍歷中做部分邊界條件終止

shiftDown 邊界定義出錯(cuò) , 正確的應(yīng)該是該元素沒有左右child后終止

shiftUp的代碼也可以優(yōu)化一些減少代碼重復(fù)判斷 , 而且邊界條件其實(shí)也沒定義好

pesudo code :



// 0 1 2 3 4 5
  [2,9,8,5,1,7]   從0開始 , 某個(gè)節(jié)點(diǎn)的parent=(i-1)/2 , leftP=2i+1 rightP=2i+2

MaxHeap {
    data []int    
    size int   initial 0  //沒有c++的那些helper function , 額外添加一個(gè)變量存儲(chǔ)size
}

size() {
    return t.size
}

isEmpty() {
    return data.size==0
}

getParentIndex(index) {
    if index==0  //root節(jié)點(diǎn)沒parent node
        panic()

    return (i-1)/2
}

getLeftIndex(index) {
    return 2i+1
}

getRightIndex(index) {
    return 2i+2
}

//put into arr last , then shift up
add(value) {
    append(data,value)
    t.size++
    newValueIndex = t.size-1
    t.shiftUp(newValueIndex)
}

// if parent less than current , swap , then repeat until root
shiftUp(index) {

    parent=t.getParentIndex(index)


    for parent!=0 {      // 優(yōu)化,小于的時(shí)候就停止了,不需要一直遍歷到root
        if data[index]>data[parent] {
            swap
        }
        index=parent
        parent=t.getParentIndex(index)
    }
}


// store data[0] which is max , then swap last value with data[0] , execute shiftDown at zero idnex
extractMax() {
    max=data[0]

    data[0]=data[t.size()-1]
    t.size-- // soft delete 

    t.shiftDown(0)
}

swap(v1,v2) {
    tmp=v1
    v1=v2
    v2=tmp
}


    1
 3    2

// main concern is to find another bigger num float to top
// find biggest from [left,right] , if current less than it , swap , until current bigger than the biggest
shiftDown(index) {
    //優(yōu)化了一遍,去除了重復(fù)代碼
    for  index.leftChild<t.size-1  // 排除沒有child的情況

        //find  leftindex , right index
        leftIndex = t.leftChild(index)
        rightIndex= t.rightChild(index)

        //find biggest
        if t.data[leftIndex]>t.data[rightIndex] 
            bV=left
            bI=leftIndex

        if current>bV {
            break
        }

        swap(data[index],biggest)
        index=biggestIndex
}



                    




最大堆

go implementation:

package main

import "fmt"

type MaxHeap struct {
    data []int
    size int
}

func Constructor() *MaxHeap{
    return &MaxHeap{}
}

func (t *MaxHeap) sizes() int{
    return t.size
}

func (t *MaxHeap) isEmpty() bool{
    return t.size==0
}

func (t *MaxHeap) parent(index int) int{
    if index==0 {
        panic("index 0 dont have parent")
    }
    return (index-1)/2
}

func (t *MaxHeap) leftChild(index int) int{
    return 2*index+1
}

func (t *MaxHeap) rightChild(index int) int{
    return 2*index+2
}

func (t *MaxHeap) add(v int) {
    t.data=append(t.data,v)
    t.size++
    newValueIndex := t.size-1

    if newValueIndex!=0 {
        t.shiftUp(newValueIndex)
    }
}

func (t *MaxHeap) shiftUp(index int) {

    parent:=t.parent(index)

    for parent>=0 && t.data[index]>t.data[parent] {
        tmp:=t.data[index]
        t.data[index]=t.data[parent]
        t.data[parent]=tmp

        index=parent

        if parent==0 {
            break
        }
        parent= t.parent(index)
    }
}

func (t *MaxHeap) extractMax() int{
    max:=t.data[0]

    t.data[0]=t.data[t.size-1]
    t.size--
    t.data=t.data[:t.size] //移除最后一個(gè)元素,其實(shí)也可以不用刪吧
    t.shiftDown(0)
    return max
}

func (t *MaxHeap) shiftDown(index int) {


    for t.leftChild(index)<=t.size-1 && t.rightChild(index)<=t.size-1 {
        leftIndex:=t.leftChild(index)
        rightIndex:=t.rightChild(index)

        var bV int
        var bI int
        if t.data[leftIndex]>t.data[rightIndex] {
            bV=t.data[leftIndex]
            bI=leftIndex
        } else {
            bV=t.data[rightIndex]
            bI=rightIndex
        }
        if t.data[index]>bV {
            break
        }

        tmp:=t.data[index]
        t.data[index]=bV
        t.data[bI]=tmp
        index=bI
    }

}


func main() {
    m:=Constructor()
    println(m.sizes())
    m.add(1)
    m.add(2)
    m.add(3)
    m.add(4)
    m.add(5)
    m.add(6)
    m.add(7)
    m.add(8)
    fmt.Println(m.data)
    fmt.Println(m.extractMax())
    fmt.Println(m.data)
    fmt.Println(m.size)
}











Max Heap 最大堆實(shí)現(xiàn)

畫了個(gè)圖檢驗(yàn)了一下這個(gè)簡(jiǎn)單測(cè)試用例

Max Heap 最大堆實(shí)現(xiàn)

參考的老師的圖

Max Heap 最大堆實(shí)現(xiàn)

最小堆

package main

import "fmt"

//minheap只要把maxheap的shiftup shiftdown 箭頭反轉(zhuǎn)一下就可以了 ,把小元素網(wǎng)上浮,大元素往下沉
type MinHeap struct {
    data []int
    size int
}

func Constructor() *MinHeap{
    return &MinHeap{}
}

func (t *MinHeap) sizes() int{
    return t.size
}

func (t *MinHeap) isEmpty() bool{
    return t.size==0
}

func (t *MinHeap) parent(index int) int{
    if index==0 {
        panic("index 0 dont have parent")
    }
    return (index-1)/2
}

func (t *MinHeap) leftChild(index int) int{
    return 2*index+1
}

func (t *MinHeap) rightChild(index int) int{
    return 2*index+2
}

func (t *MinHeap) add(v int) {
    t.data=append(t.data,v)
    t.size++
    newValueIndex := t.size-1

    if newValueIndex!=0 {
        t.shiftUp(newValueIndex)
    }
}

func (t *MinHeap) shiftUp(index int) {

    parent:=t.parent(index)

    for parent>=0 && t.data[index]<t.data[parent] {
        tmp:=t.data[index]
        t.data[index]=t.data[parent]
        t.data[parent]=tmp

        index=parent

        if parent==0 {
            break
        }
        parent= t.parent(index)
    }
}

func (t *MinHeap) extractMin() int{
    min:=t.data[0]

    t.data[0]=t.data[t.size-1]
    t.size--
    t.data=t.data[:t.size] //移除最后一個(gè)元素,其實(shí)也可以不用刪吧
    t.shiftDown(0)
    return min
}

func (t *MinHeap) shiftDown(index int) {


    for t.leftChild(index)<=t.size-1 && t.rightChild(index)<=t.size-1 {
        leftIndex:=t.leftChild(index)
        rightIndex:=t.rightChild(index)

        var bV int
        var bI int
        if t.data[leftIndex]<t.data[rightIndex] {
            bV=t.data[leftIndex]
            bI=leftIndex
        } else {
            bV=t.data[rightIndex]
            bI=rightIndex
        }
        if t.data[index]<bV {
            break
        }

        tmp:=t.data[index]
        t.data[index]=bV
        t.data[bI]=tmp
        index=bI
    }
}


func main() {
    m:=Constructor()
    m.add(1)
    m.add(2)
    m.add(3)
    m.add(4)
    m.add(5)
    m.add(6)
    m.add(7)
    m.add(8)
    fmt.Println(m.data)
    fmt.Println(m.size)
    fmt.Println(m.extractMin())
    fmt.Println(m.data)
    fmt.Println(m.size)
    fmt.Println(m.extractMin())
    fmt.Println(m.extractMin())
    fmt.Println(m.extractMin())
    fmt.Println(m.extractMin())
    fmt.Println(m.extractMin())
    fmt.Println(m.extractMin())
    fmt.Println(m.extractMin())
}











優(yōu)先隊(duì)列

優(yōu)先隊(duì)列這里妥妥的就是一個(gè)適配器模式的典例

package main

type PriorityQueue struct {
    maxHeap *MaxHeap
}

func (t *PriorityQueue) size() int{
    return t.maxHeap.sizes()
}

func (t *PriorityQueue) isEmpty() bool{
    return t.maxHeap.isEmpty()
}


func (t *PriorityQueue) front() int{
    if t.size()==0 {
        panic("queue is empty")
    }
    return t.maxHeap.data[0]
}

func (t *PriorityQueue) enqueue(v int){
    t.maxHeap.add(v)
}
func (t *PriorityQueue) dequeue(){
    t.maxHeap.extractMax()
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末扼劈,一起剝皮案震驚了整個(gè)濱河市驻啤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌测僵,老刑警劉巖街佑,帶你破解...
    沈念sama閱讀 218,451評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異捍靠,居然都是意外死亡沐旨,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門榨婆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來磁携,“玉大人,你說我怎么就攤上這事良风∫昶” “怎么了?”我有些...
    開封第一講書人閱讀 164,782評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵烟央,是天一觀的道長(zhǎng)统诺。 經(jīng)常有香客問我,道長(zhǎng)疑俭,這世上最難降的妖魔是什么粮呢? 我笑而不...
    開封第一講書人閱讀 58,709評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮钞艇,結(jié)果婚禮上啄寡,老公的妹妹穿的比我還像新娘。我一直安慰自己哩照,他們只是感情好挺物,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著飘弧,像睡著了一般识藤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上次伶,一...
    開封第一講書人閱讀 51,578評(píng)論 1 305
  • 那天蹋岩,我揣著相機(jī)與錄音,去河邊找鬼学少。 笑死剪个,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播扣囊,決...
    沈念sama閱讀 40,320評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼乎折,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了侵歇?” 一聲冷哼從身側(cè)響起骂澄,我...
    開封第一講書人閱讀 39,241評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎惕虑,沒想到半個(gè)月后坟冲,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,686評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡溃蔫,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評(píng)論 3 336
  • 正文 我和宋清朗相戀三年健提,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片伟叛。...
    茶點(diǎn)故事閱讀 39,992評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡私痹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出统刮,到底是詐尸還是另有隱情紊遵,我是刑警寧澤,帶...
    沈念sama閱讀 35,715評(píng)論 5 346
  • 正文 年R本政府宣布侥蒙,位于F島的核電站暗膜,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏鞭衩。R本人自食惡果不足惜学搜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望醋旦。 院中可真熱鬧,春花似錦会放、人聲如沸饲齐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)捂人。三九已至,卻和暖如春矢沿,著一層夾襖步出監(jiān)牢的瞬間滥搭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工捣鲸, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留瑟匆,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,173評(píng)論 3 370
  • 正文 我出身青樓栽惶,卻偏偏與公主長(zhǎng)得像愁溜,于是被迫代替她去往敵國(guó)和親疾嗅。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,103評(píng)論 1 32
  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5冕象? 答:HTML5是最新的HTML標(biāo)準(zhǔn)代承。 注意:講述HT...
    kismetajun閱讀 27,486評(píng)論 1 45
  • 等一樹花來,等冬去春來渐扮,也等你论悴,漫山飛雪,踏雪尋梅墓律,雙全足跡膀估,從此真情
    簡(jiǎn)生在太原街角閱讀 310評(píng)論 0 3
  • 最近不斷有家長(zhǎng)們聯(lián)系我玖像,問什么時(shí)候重新開課。感恩大家伙兒的信任支持齐饮。本來在臥龍租下的三層別墅捐寥,我和三哥花了許多時(shí)間...
    蘭西蘇閱讀 1,200評(píng)論 0 4
  • 我們身處社會(huì)之中,就必然要與人打交道祖驱,人與人的接觸握恳,印象有多重要呢? 先看看下面這個(gè)例子捺僻! Allen是一個(gè)聰明乡洼,...
    哇啦啦啦啦啦啦閱讀 475評(píng)論 0 5