GO語言實現(xiàn)堆夯到、棧嚷缭、隊列、優(yōu)先級隊列

前言

C++耍贾、java等語言都實現(xiàn)了棧阅爽、堆、隊列荐开、優(yōu)先級隊列等付翁。但是Go語言卻沒有。我們在實際使用中卻是需要這些基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)晃听,怎么辦百侧?自己造!

heap && priority_queue

go語言有標(biāo)準(zhǔn)容器庫 "container/heap"能扒,我們可以根據(jù)這個庫來實現(xiàn)堆以及優(yōu)先級隊列:
先看 "container/heap" 里的定義:

type Interface interface {
    sort.Interface
    Push(x interface{}) // add x as element Len()
    Pop() interface{}   // remove and return element Len() - 1.
}

這個堆使用的數(shù)據(jù)結(jié)構(gòu)是最小二叉樹佣渴,即根節(jié)點比左邊子樹和右邊子樹的所有值都小,其中 sort.Interface的定義如下:

type Interface interface {
    // Len is the number of elements in the collection.
    Len() int
    // Less reports whether the element with
    // index i should sort before the element with index j.
    Less(i, j int) bool
    // Swap swaps the elements with indexes i and j.
    Swap(i, j int)
}

所以要實現(xiàn)這五個接口就可以了~初斑,話不多說辛润,開干!

實現(xiàn)堆

// intHeap 實現(xiàn)了 heap 的接口
package kit

import (
    "container/heap"
)

type intHeap []int

func (h intHeap) Len() int {
    return len(h)
}

func (h intHeap) Less(i, j int) bool {
    return h[i] < h[j]
}

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

func (h *intHeap) Push(x interface{}) {
    // Push 使用 *h,是因為
    // Push 增加了 h 的長度
    *h = append(*h, x.(int))
}

func (h *intHeap) Pop() interface{} {
    // Pop 使用 *h 见秤,是因為
    // Pop 減短了 h 的長度
    res := (*h)[len(*h)-1]
    *h = (*h)[:len(*h)-1]
    return res
}

實現(xiàn)優(yōu)先級隊列

package kit

import (
    "container/heap"
)
//以下實現(xiàn)優(yōu)先級隊列
// This example demonstrates a priority queue built using the heap interface.
// entry 是 priorityQueue 中的元素
type entry struct {
    key      string
    priority int
    // index 是 entry 在 heap 中的索引號
    // entry 加入 Priority Queue 后砂竖, Priority 會變化時,很有用
    // 如果 entry.priority 一直不變的話鹃答,可以刪除 index
    index int
}

// PQ implements heap.Interface and holds entries.
type PQ []*entry

func (pq PQ) Len() int { return len(pq) }

func (pq PQ) Less(i, j int) bool {
    return pq[i].priority < pq[j].priority
}

func (pq PQ) Swap(i, j int) {
    pq[i], pq[j] = pq[j], pq[i]
    pq[i].index = i
    pq[j].index = j
}

// Push 往 pq 中放 entry
func (pq *PQ) Push(x interface{}) {
    temp := x.(*entry)
    temp.index = len(*pq)
    *pq = append(*pq, temp)
}

// Pop 從 pq 中取出最優(yōu)先的 entry
func (pq *PQ) Pop() interface{} {
    temp := (*pq)[len(*pq)-1]
    temp.index = -1 // for safety
    *pq = (*pq)[0 : len(*pq)-1]
    return temp
}

// update modifies the priority and value of an entry in the queue.
func (pq *PQ) update(entry *entry, value string, priority int) {
    entry.key = value
    entry.priority = priority
    heap.Fix(pq, entry.index)
}

stack && queue

采用go里的slice結(jié)構(gòu)實現(xiàn)棧和隊列

package kit
// Stack 是用于存放 int 的 棧
type Stack struct {
    nums []int
}

// NewStack 返回 *kit.Stack
func NewStack() *Stack {
    return &Stack{nums: []int{}}
}

// Push 把 n 放入 棧
func (s *Stack) Push(n int) {
    s.nums = append(s.nums, n)
}

// Pop 從 s 中取出最后放入 棧 的值
func (s *Stack) Pop() int {
    res := s.nums[len(s.nums)-1]
    s.nums = s.nums[:len(s.nums)-1]
    return res
}

// Len 返回 s 的長度
func (s *Stack) Len() int {
    return len(s.nums)
}

// IsEmpty 反饋 s 是否為空
func (s *Stack) IsEmpty() bool {
    return s.Len() == 0
}

隊列

package kit
// Queue 是用于存放 int 的隊列
type Queue struct {
    nums []int
}

// NewQueue 返回 *kit.Queue
func NewQueue() *Queue {
    return &Queue{nums: []int{}}
}

// Push 把 n 放入隊列
func (q *Queue) Push(n int) {
    q.nums = append(q.nums, n)
}

// Pop 從 q 中取出最先進(jìn)入隊列的值
func (q *Queue) Pop() int {
    res := q.nums[0]
    q.nums = q.nums[1:]
    return res
}

// Len 返回 q 的長度
func (q *Queue) Len() int {
    return len(q.nums)
}

// IsEmpty 反饋 q 是否為空
func (q *Queue) IsEmpty() bool {
    return q.Len() == 0
}

好啦乎澄,這樣我們就可以直接使用自定義的kit包來操作棧、隊列测摔、堆以及優(yōu)先級隊列在我們的代碼里了~ 是不是超簡單~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末置济,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌舟肉,老刑警劉巖修噪,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異路媚,居然都是意外死亡黄琼,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進(jìn)店門整慎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來脏款,“玉大人,你說我怎么就攤上這事裤园〕肥Γ” “怎么了?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵拧揽,是天一觀的道長剃盾。 經(jīng)常有香客問我,道長淤袜,這世上最難降的妖魔是什么痒谴? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮铡羡,結(jié)果婚禮上积蔚,老公的妹妹穿的比我還像新娘。我一直安慰自己烦周,他們只是感情好尽爆,可當(dāng)我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著读慎,像睡著了一般漱贱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上夭委,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天幅狮,我揣著相機(jī)與錄音,去河邊找鬼闰靴。 笑死,一個胖子當(dāng)著我的面吹牛钻注,可吹牛的內(nèi)容都是我干的蚂且。 我是一名探鬼主播,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼幅恋,長吁一口氣:“原來是場噩夢啊……” “哼杏死!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤淑翼,失蹤者是張志新(化名)和其女友劉穎腐巢,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體玄括,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡冯丙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了遭京。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片胃惜。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖哪雕,靈堂內(nèi)的尸體忽然破棺而出船殉,到底是詐尸還是另有隱情,我是刑警寧澤斯嚎,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布利虫,位于F島的核電站,受9級特大地震影響堡僻,放射性物質(zhì)發(fā)生泄漏糠惫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一苦始、第九天 我趴在偏房一處隱蔽的房頂上張望寞钥。 院中可真熱鬧,春花似錦陌选、人聲如沸理郑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽您炉。三九已至,卻和暖如春役电,著一層夾襖步出監(jiān)牢的瞬間赚爵,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工法瑟, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留冀膝,地道東北人。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓霎挟,卻偏偏與公主長得像窝剖,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子酥夭,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,877評論 2 345