forked from wangzheng0822/algo
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
lixingliang
committed
Mar 15, 2019
1 parent
1a16bc2
commit 7612aa0
Showing
5 changed files
with
175 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package pqueue | ||
|
||
func adjustHeap(src []Node, start, end int) { | ||
if start >= end { | ||
return | ||
} | ||
|
||
// 只需要保证优先级最高的节点在 src[1] 的位置即可 | ||
for i := end / 2; i >= start; i-- { | ||
high := i | ||
if src[high].priority < src[2*i].priority { | ||
high = 2 * i | ||
} | ||
if 2*i+1 <= end && src[high].priority < src[2*i+1].priority { | ||
high = 2*i + 1 | ||
} | ||
if high == i { | ||
continue | ||
} | ||
src[high], src[i] = src[i], src[high] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package pqueue | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func Test_AdjustHeap(t *testing.T) { | ||
list := []Node{Node{0, 0}, Node{1, 1}, Node{2, 2}, Node{3, 3}, Node{4, 1}, Node{6, 6}} | ||
|
||
adjustHeap(list, 1, len(list)-1) | ||
assert.Equal(t, 6, list[1].value) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package pqueue | ||
|
||
// Node 队列节点 | ||
type Node struct { | ||
value int | ||
priority int | ||
} | ||
|
||
// PQueue priority queue | ||
type PQueue struct { | ||
heap []Node | ||
|
||
capacity int | ||
used int | ||
} | ||
|
||
// NewPriorityQueue new | ||
func NewPriorityQueue(capacity int) PQueue { | ||
return PQueue{ | ||
heap: make([]Node, capacity+1, capacity+1), | ||
capacity: capacity, | ||
used: 0, | ||
} | ||
} | ||
|
||
// Push 入队 | ||
func (q *PQueue) Push(node Node) { | ||
|
||
if q.used > q.capacity { | ||
// 队列已满 | ||
return | ||
} | ||
q.used++ | ||
q.heap[q.used] = node | ||
// 堆化可以放在 Pop 中 | ||
// adjustHeap(q.heap, 1, q.used) | ||
} | ||
|
||
// Pop 出队列 | ||
func (q *PQueue) Pop() Node { | ||
if q.used == 0 { | ||
return Node{-1, -1} | ||
} | ||
// 先堆化, 再取堆顶元素 | ||
adjustHeap(q.heap, 1, q.used) | ||
node := q.heap[1] | ||
|
||
q.heap[1] = q.heap[q.used] | ||
q.used-- | ||
|
||
return node | ||
} | ||
|
||
// Top 获取队列顶部元素 | ||
func (q *PQueue) Top() Node { | ||
if q.used == 0 { | ||
return Node{-1, -1} | ||
} | ||
|
||
adjustHeap(q.heap, 1, q.used) | ||
return q.heap[1] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package pqueue | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func Test_Push(t *testing.T) { | ||
queue := NewPriorityQueue(100) | ||
|
||
queue.Push(Node{0, 1}) | ||
assert.Equal(t, 0, queue.Top().value) | ||
|
||
queue.Push(Node{3, 1}) | ||
assert.Equal(t, 0, queue.Top().value) | ||
|
||
queue.Push(Node{3, 2}) | ||
assert.Equal(t, 3, queue.Top().value) | ||
|
||
queue.Push(Node{6, 6}) | ||
assert.Equal(t, 6, queue.Top().value) | ||
|
||
queue.Push(Node{12, 5}) | ||
assert.Equal(t, 6, queue.Top().value) | ||
|
||
queue.Push(Node{13, 8}) | ||
assert.Equal(t, 13, queue.Top().value) | ||
} | ||
|
||
func Test_PushPop(t *testing.T) { | ||
queue := NewPriorityQueue(100) | ||
|
||
queue.Push(Node{0, 1}) | ||
queue.Push(Node{3, 1}) | ||
queue.Push(Node{3, 2}) | ||
queue.Push(Node{6, 6}) | ||
queue.Push(Node{12, 5}) | ||
queue.Push(Node{13, 8}) | ||
assert.Equal(t, 13, queue.Top().value) | ||
|
||
assert.Equal(t, 13, queue.Pop().value) | ||
assert.Equal(t, 6, queue.Pop().value) | ||
assert.Equal(t, 12, queue.Top().value) | ||
assert.Equal(t, 12, queue.Pop().value) | ||
|
||
queue.Push(Node{24, 8}) | ||
assert.Equal(t, 24, queue.Top().value) | ||
} | ||
|
||
// 无法保证入队顺序和出队顺序的一致性 | ||
// func Test_PushPop_Equal(t *testing.T) { | ||
// queue := NewPriorityQueue(9) | ||
|
||
// queue.Push(Node{0, 1}) // 8 | ||
// queue.Push(Node{3, 1}) // 9 | ||
// queue.Push(Node{3, 2}) // 3 | ||
// queue.Push(Node{6, 2}) // 4 | ||
// queue.Push(Node{11, 3}) // 2 | ||
// queue.Push(Node{12, 2}) // 5 | ||
// queue.Push(Node{13, 2}) // 6 | ||
// queue.Push(Node{19, 5}) // 1 | ||
// queue.Push(Node{17, 2}) // 7 | ||
|
||
// assert.Equal(t, 19, queue.Pop().value) | ||
// assert.Equal(t, 11, queue.Pop().value) | ||
// assert.Equal(t, 3, queue.Pop().value) | ||
// assert.Equal(t, 6, queue.Pop().value) | ||
// assert.Equal(t, 12, queue.Pop().value) | ||
// assert.Equal(t, 13, queue.Pop().value) | ||
// assert.Equal(t, 17, queue.Pop().value) | ||
// assert.Equal(t, 0, queue.Pop().value) | ||
// assert.Equal(t, 3, queue.Pop().value) | ||
// } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
|
||
## TODO | ||
- 该实现方式不能保证 相同优先级的元素在出队列时 和入队列的顺序是一致的 |