近期要用golang 实现一个优先队列,优先队列的实现最早是在 c语言书籍:

参考书籍:

<<数据结构和算法c>> 

小根堆实现:

package main

import "fmt"

type StreamPriorityQueueData struct {
	key   int
	value int
}

type StreamPriorityQueue struct {
	caches   []StreamPriorityQueueData
	size     int
	capacity int
}

func NewStreamPriorityQueue(size int) *StreamPriorityQueue {
	return &StreamPriorityQueue{
		caches:   make([]StreamPriorityQueueData, size),
		capacity: size,
	}
}

func (q *StreamPriorityQueue) GetQueueTop() StreamPriorityQueueData {
	if len(q.caches) == 0 {
		return StreamPriorityQueueData{}
	}

	return q.caches[0]
}

func (q *StreamPriorityQueue) EnQueue(data StreamPriorityQueueData) {
	if q.size == q.capacity {
		return
	}

	q.size++

	var i int
	for i = q.size; q.caches[i/2].key > data.key; i /= 2 {
		q.caches[i] = q.caches[i/2]
	}
	q.caches[i] = data
}

func (q *StreamPriorityQueue) DeQueue() StreamPriorityQueueData {
	if q.size == 0 {
		return q.caches[0]
	}

	minElements := q.caches[1]
	lastElements := q.caches[(q.size)]

	var i int
	var child int

	for i = 1; i*2 <= q.size; i = child {
		child = i * 2

		//左右子节点比较,选较小的一方
		if child != q.size && (q.caches[child+1].key < q.caches[child].key) {
			child++
		}

		//最后一个元素和子节点比较,如果最后一个元素大,上提子节点
		if lastElements.key > q.caches[child].key {
			q.caches[i] = q.caches[child]
		} else {
			break
		}
	}
	q.caches[i] = lastElements
	fmt.Println(minElements)
	return minElements
}

func main() {
	q := NewStreamPriorityQueue(8)
	d := StreamPriorityQueueData{
		key:   1,
		value: 1,
	}
	q.EnQueue(d)

	d1 := StreamPriorityQueueData{
		key:   2,
		value: 2,
	}
	q.EnQueue(d1)

	d2 := StreamPriorityQueueData{
		key:   3,
		value: 3,
	}
	q.EnQueue(d2)

	d3 := StreamPriorityQueueData{
		key:   4,
		value: 4,
	}
	q.EnQueue(d3)

	d4 := StreamPriorityQueueData{
		key:   5,
		value: 5,
	}
	q.EnQueue(d4)

	q.DeQueue()
	q.DeQueue()
	q.DeQueue()
	q.DeQueue()
	q.DeQueue()

	q.EnQueue(d3)
	q.DeQueue()

}

大根堆实现:

package main

import "fmt"

type StreamPriorityQueueData struct {
	key   int
	value int
}

type StreamPriorityQueue struct {
	caches   []StreamPriorityQueueData
	size     int
	capacity int
}

func NewStreamPriorityQueue(size int) *StreamPriorityQueue {
	return &StreamPriorityQueue{
		caches:   make([]StreamPriorityQueueData, size),
		capacity: size,
	}
}

func (q *StreamPriorityQueue) GetQueueTop() StreamPriorityQueueData {
	if len(q.caches) == 0 {
		return StreamPriorityQueueData{}
	}

	return q.caches[0]
}

func (q *StreamPriorityQueue) swap(x *StreamPriorityQueueData, y *StreamPriorityQueueData) {
	tmp := *x
	*x = *y
	*y = tmp
}

func (q *StreamPriorityQueue) adjustUp() {
	child := q.size
	parent := (child - 1) / 2
	for q.caches[parent].key < q.caches[child].key {
		q.swap(&(q.caches[parent]), &(q.caches[child])) //进行交换
		child = parent
		parent = (child - 1) / 2
	}
}

func (q *StreamPriorityQueue) adjustDown(n int, parent int) {
	child := parent*2 + 1
	for child < n {
		//比较左孩子还是右孩子大
		if child+1 < n && q.caches[child+1].key > q.caches[child].key {
			child++
		}
		if q.caches[child].key > q.caches[parent].key {
			q.swap(&q.caches[child], &q.caches[parent])
			parent = child
			child = parent*2 + 1
		} else {
			break
		}
	}
}

func (q *StreamPriorityQueue) EnQueue(data StreamPriorityQueueData) {
	if q.size == q.capacity {
		return
	}
	q.caches[q.size] = data
	q.adjustUp()
	q.size++
}

func (q *StreamPriorityQueue) DeQueue() StreamPriorityQueueData {
	if q.size == 0 {
		return q.caches[0]
	}

	q.swap(&q.caches[0], &q.caches[q.size-1])
	q.size--
	q.adjustDown(q.size, 0)
	return q.caches[q.size]
}

func main() {
	q := NewStreamPriorityQueue(8)
	d := StreamPriorityQueueData{
		key:   1,
		value: 1,
	}
	q.EnQueue(d)

	d1 := StreamPriorityQueueData{
		key:   2,
		value: 2,
	}
	q.EnQueue(d1)

	d2 := StreamPriorityQueueData{
		key:   3,
		value: 3,
	}
	q.EnQueue(d2)

	d3 := StreamPriorityQueueData{
		key:   4,
		value: 4,
	}
	q.EnQueue(d3)

	d4 := StreamPriorityQueueData{
		key:   5,
		value: 5,
	}
	q.EnQueue(d4)

	fmt.Println(q.DeQueue().key)
	fmt.Println(q.DeQueue().key)
	fmt.Println(q.DeQueue().key)
	fmt.Println(q.DeQueue().key)
	fmt.Println(q.DeQueue().key)
	fmt.Println(q.DeQueue().key)

}