File tree Expand file tree Collapse file tree 3 files changed +195
-0
lines changed
Expand file tree Collapse file tree 3 files changed +195
-0
lines changed Original file line number Diff line number Diff line change 1+ package heap
2+
3+ import (
4+ "sync"
5+ )
6+
7+ type Item interface {
8+ Less (than Item ) bool
9+ }
10+
11+ type Heap struct {
12+ data []Item
13+ min bool
14+ mutex sync.Mutex
15+ }
16+
17+ // 新建一个堆
18+ func New () * Heap {
19+ newHeap := & Heap {
20+ data : make ([]Item , 0 ),
21+ }
22+ return newHeap
23+ }
24+
25+ // 新建一个小顶堆
26+ func NewMin () * Heap {
27+ newHeap := & Heap {
28+ data : make ([]Item , 0 ),
29+ min : true ,
30+ }
31+ return newHeap
32+ }
33+
34+ // 新建一个大顶堆
35+ func NewMax () * Heap {
36+ newHeap := & Heap {
37+ data : make ([]Item , 0 ),
38+ min : false ,
39+ }
40+ return newHeap
41+ }
42+
43+ // 堆是否为空
44+ func (h * Heap ) IsEmpty () bool {
45+ return len (h .data ) == 0
46+ }
47+
48+ // 堆大小
49+ func (h * Heap ) Size () int {
50+ return len (h .data )
51+ }
52+
53+ // 获取元素
54+ func (h * Heap ) Get (index int ) Item {
55+ return h .data [index ]
56+ }
57+
58+ // 插入元素
59+ func (h * Heap ) Insert (n Item ) {
60+ h .mutex .Lock ()
61+ defer h .mutex .Unlock ()
62+ {
63+ h .data = append (h .data , n )
64+ h .siftUp ()
65+ return
66+ }
67+ }
68+
69+ // 取出元素
70+ func (h * Heap ) Extract () (element Item ) {
71+ h .mutex .Lock ()
72+ defer h .mutex .Unlock ()
73+ {
74+ if h .Size () == 0 {
75+ return
76+ }
77+ element = h .data [0 ]
78+ last := h .data [h .Size ()- 1 ]
79+ if h .Size () == 1 {
80+ h .data = nil
81+ return
82+ }
83+ h .data = append ([]Item {last }, h .data [1 :h .Size ()- 1 ]... )
84+ h .siftDown ()
85+ return
86+ }
87+ }
88+
89+ // 上移操作
90+ func (h * Heap ) siftUp () {
91+ for i , parent := h .Size ()- 1 , h .Size ()- 1 ; i > 0 ; i = parent {
92+ parent = i >> 1
93+ // 如果i位置小于 其父节点,交换
94+ if h .Less (h .Get (i ), h .Get (parent )) {
95+ h .data [parent ], h .data [i ] = h .data [i ], h .data [parent ]
96+ } else {
97+ break
98+ }
99+ }
100+ }
101+
102+ // 下移操作
103+ func (h * Heap ) siftDown () {
104+ for i , child := 0 , 1 ; i < h .Size () && i << 1 + 1 < h .Size (); i = child {
105+ child = i << 1 + 1
106+ // 两个孩子节点之间交换
107+ if child + 1 <= h .Size ()- 1 && h .Less (h .Get (child + 1 ), h .Get (child )) {
108+ child ++
109+ }
110+ // 父节点如果小于子节点,交换
111+ if h .Less (h .Get (i ), h .Get (child )) {
112+ break
113+ }
114+ }
115+ }
116+
117+
118+ func (h * Heap ) Less (a , b Item ) bool {
119+ if h .min {
120+ return a .Less (b )
121+ } else {
122+ return b .Less (a )
123+ }
124+ }
Original file line number Diff line number Diff line change 1+ /**
2+ * Author: Juntaran
3+ * Email: Jacinthmail@gmail.com
4+ * Date: 2017/4/15 10:51
5+ */
6+
7+ package main
8+
9+ import (
10+ "Golang_Algorithm/Data_Structure/Heap"
11+ "fmt"
12+ "log"
13+ )
14+
15+ func main () {
16+ // 最小堆测试
17+ h1 := heap .NewMin ()
18+ h1 .Insert (heap .Int (8 ))
19+ h1 .Insert (heap .Int (7 ))
20+ h1 .Insert (heap .Int (6 ))
21+ h1 .Insert (heap .Int (3 ))
22+ h1 .Insert (heap .Int (1 ))
23+ h1 .Insert (heap .Int (0 ))
24+ h1 .Insert (heap .Int (2 ))
25+ h1 .Insert (heap .Int (4 ))
26+ h1 .Insert (heap .Int (9 ))
27+ h1 .Insert (heap .Int (5 ))
28+
29+ sorted := make ([]heap.Int , 0 )
30+ for h1 .Size () > 0 {
31+ sorted = append (sorted , h1 .Extract ().(heap.Int ))
32+ }
33+ for i := 0 ; i < len (sorted )- 2 ; i ++ {
34+ if sorted [i ] > sorted [i + 1 ] {
35+ fmt .Println (sorted )
36+ } else {
37+ log .Println ("Error" )
38+ }
39+ }
40+
41+ h2 := heap .NewMin ()
42+ h2 .Insert (heap .Int (8 ))
43+ h2 .Insert (heap .Int (7 ))
44+ h2 .Insert (heap .Int (6 ))
45+ h2 .Insert (heap .Int (3 ))
46+ h2 .Insert (heap .Int (1 ))
47+ h2 .Insert (heap .Int (0 ))
48+ h2 .Insert (heap .Int (2 ))
49+ h2 .Insert (heap .Int (4 ))
50+ h2 .Insert (heap .Int (9 ))
51+ h2 .Insert (heap .Int (5 ))
52+
53+ sorted = make ([]heap.Int , 0 )
54+ for h2 .Size () > 0 {
55+ sorted = append (sorted , h2 .Extract ().(heap.Int ))
56+ }
57+ for i := 0 ; i < len (sorted )- 2 ; i ++ {
58+ if sorted [i ] > sorted [i + 1 ] {
59+ fmt .Println (sorted )
60+ } else {
61+ log .Println ("Error" )
62+ }
63+ }
64+ }
Original file line number Diff line number Diff line change 1+ package heap
2+
3+ type Int int
4+
5+ func (x Int ) Less (than Item ) bool {
6+ return x < than .(Int )
7+ }
You can’t perform that action at this time.
0 commit comments