golang中container/heap包

任何實現(xiàn)了 heap.Interface 接口的對象都可以使用heap包提供的方法對堆進行操作(堆是一個完成二叉樹)。通過對heap.Interface 中的 Less 方法的不同實現(xiàn),來實現(xiàn)最大堆和最小堆。通常堆的數(shù)據(jù)結(jié)構(gòu)是一個一維數(shù)組。

heap包提供的函數(shù)列表:
1)func Init(h Interface)
2)func Pop(h Interface) interface{}
3)func Push(h Interface, x interface{})
4)func Remove(h Interface, i int) interface{}
5)type Interface

現(xiàn)在對提供的函數(shù)進行分析:

func Init(h Interface)
參數(shù)列表:h,實現(xiàn)了heap.Interface接口的堆對象
功能說明:在對堆h進行操作前必須保證堆已經(jīng)初始化(即符合堆結(jié)構(gòu)),該方法可以在堆中元素的順序不符合堆要求時調(diào)用,調(diào)用后堆會調(diào)整為標(biāo)準(zhǔn)的堆結(jié)構(gòu),該方法的時間復(fù)雜度為:O(n),n為堆h中元素的總個數(shù)。

前面有一個 實現(xiàn)了heap.Interface 接口的對象?那么實現(xiàn)了這個接口的對象要實現(xiàn)哪些內(nèi)容呢?

一共需要實現(xiàn)5個方法,Len、Swap、Less、Pop、Push

標(biāo)準(zhǔn)庫源碼:
type Interface interface {
    sort.Interface
    Push(x interface{})
    Pop() interface{}
}
功能:
這是堆的接口,heap包里面的方法只是提供的一些堆算法操作,要想使用這些算法操作,就必須實現(xiàn)這些接口,每個接口方法都有具體的含義,堆本身的數(shù)據(jù)結(jié)構(gòu)由這個接口的具體實現(xiàn)決定,可以是數(shù)組、列表。
接口方法:
1)sort.Interface
要實現(xiàn)三個接口:func Len() int,func Less(i, j int) bool,func Swap(i, j int),其中Less方法的實現(xiàn)決定了堆是最大堆還是最小堆。
type myHeap []int    // 定義一個堆,存儲結(jié)構(gòu)為數(shù)組

// 最小堆的Less方法實現(xiàn)
func (h *myHeap) Less(i, j int) bool {
    return (*h)[i] < (*h)[j]
}

// 最大堆的Less方法實現(xiàn)
func (h *myHeap) Less(i, j int) bool {
    return (*h)[i] > (*h)[j]
}

2)Push(x interface{})
參數(shù)列表:x將存到堆中的元素
功能說明:把元素x存放到切片最末尾。
func (h *myHeap) Push(v interface{}) {
    *h = append(*h, v.(int))
}

3)Pop() interface{}
返回值:移除切片末尾的那個元素
功能說明:把最后一個元素移除并將其值返回。
func (h *myHeap) Pop() (v interface{}) {
    *h, v = (*h)[:h.Len()-1], (*h)[h.Len()-1]
    return
}

編寫一個應(yīng)用heap包的案例:

package main

import (
    "fmt"
    "container/heap"
)

type myHeap []int

/* 實現(xiàn)排序 */
func (h *myHeap) Len() int {
    return len(*h)
}

func (h *myHeap) Swap(i, j int) {
    (*h)[i], (*h)[j] = (*h)[j], (*h)[i]
}

// 最小堆實現(xiàn)
func (h *myHeap) Less(i, j int) bool {
    return (*h)[i] < (*h)[j]
}

/* 實現(xiàn)往堆中添加元素 */
func (h *myHeap)Push(v interface{}) {
    *h = append(*h, v.(int))
}

/* 實現(xiàn)刪除堆中元素 */
func (h *myHeap)Pop() (v interface{}) {
    *h, v = (*h)[:len(*h)-1], (*h)[len(*h)-1]
    return
}

// 按層來遍歷和打印堆數(shù)據(jù),第一行只有一個元素,即堆頂元素
func (h myHeap) printHeap() {
    n := 1
    levelCount := 1
    for n <= h.Len() {
        fmt.Println(h[n-1 : n-1+levelCount])
        n += levelCount
        levelCount *= 2
    }
}

func main() {
    data := [7]int{13,12,45,23,11,9,20}
    aHeap := new(myHeap)
    for i := 0;i < len(data);i++ {
        aHeap.Push(data[i])
    }
    aHeap.printHeap()

    // 堆排序處理
    heap.Init(aHeap)
    aHeap.printHeap()
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容