Skip to content

Commit 686cbb7

Browse files
committed
Merge branch 'dev'
2 parents a8e8e31 + c2397b9 commit 686cbb7

8 files changed

+240
-5
lines changed

Readme.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ it's some data struct using golang
77
- [x] Binary tree
88
- [x] Stack
99
- [x] Queue
10-
- [ ] Heap
10+
- [x] Heap
1111
- [ ] B/B+ tree

binarytree.go

+21-4
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,27 @@ func (bt *BinaryTree) PreOrderTraverseRecursive(f BinaryTreeHandleFunc, e Binary
6565
r.PreOrderTraverseRecursive(f, e)
6666
}
6767

68-
// func (bt *BinaryTree) PreOrderTraverseStack(f BinaryTreeHandleFunc, e BinaryTreeErrorHandleFunc) {
69-
// // now we do not have stack data struct
70-
// panic("Sorry we do not have stack now")
71-
// }
68+
//PreOrderTraverseStack is a stack based pre-order traversal
69+
func (bt *BinaryTree) PreOrderTraverseStack(f BinaryTreeHandleFunc, e BinaryTreeErrorHandleFunc) {
70+
//now we use a stack to do the traversal
71+
var s = make([]*BinaryTreeNode, 0)
72+
s = append(s, bt.Root)
73+
for len(s) > 0 {
74+
h := s[len(s)-1]
75+
s = s[:len(s)-1]
76+
err := f(h)
77+
if err != nil {
78+
e(err)
79+
}
80+
if h.Right != nil {
81+
s = append(s, h.Right)
82+
}
83+
if h.Left != nil {
84+
s = append(s, h.Left)
85+
}
86+
}
87+
88+
}
7289

7390
func (bt *BinaryTree) InOrderTraverseRecursive(f BinaryTreeHandleFunc, e BinaryTreeErrorHandleFunc) {
7491
tNode := bt.Root

binarytree_test.go

+22
Original file line numberDiff line numberDiff line change
@@ -236,3 +236,25 @@ func TestBinaryTreeDeep(t *testing.T) {
236236
t.Errorf("BinaryTree: Deep error: it should be 3 but get %d", tree.Deep())
237237
}
238238
}
239+
240+
//TestBinaryTreePreOrderTraverseStack
241+
func TestBinaryTreePreOrderTraverseStack(t *testing.T) {
242+
tree := NewBinaryTreeFromNode(NewBinaryTreeNode(1))
243+
tree.Root.Left = NewBinaryTreeNode(2)
244+
tree.Root.Right = NewBinaryTreeNode(3)
245+
tree.Root.Left.Left = NewBinaryTreeNode(4)
246+
tree.Root.Left.Right = NewBinaryTreeNode(5)
247+
248+
var buf bytes.Buffer
249+
250+
tree.PreOrderTraverseStack(func(node *BinaryTreeNode) error {
251+
buf.WriteString(node.String())
252+
return nil
253+
}, func(err error) {
254+
t.Error(err)
255+
})
256+
257+
if buf.String() != "12453" {
258+
t.Errorf("BinaryTree: TestBinaryTreePreOrderTraverseStack error: buf.String() should be '12453' but is '%s'", buf.String())
259+
}
260+
}

heap.go

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package datastruct
2+
3+
import "container/heap"
4+
5+
//Len returns the length of the heap
6+
func (h *Heap) Len() int {
7+
return h.length
8+
}
9+
10+
//Less returns true if the element at index i is less than the element at index j
11+
func (h *Heap) Less(i, j int) bool {
12+
ii, _ := h.Index(h.length - i - 1)
13+
ji, _ := h.Index(h.length - j - 1)
14+
in := ii.Value.(*HeapNode)
15+
jn := ji.Value.(*HeapNode)
16+
//use priority to compare and ismax to decide whether it is a max heap or min heap
17+
return (in.Priority > jn.Priority) == h.ismax
18+
}
19+
20+
//Swap swaps the elements at index i and j
21+
func (h *Heap) Swap(i, j int) {
22+
ii, _ := h.Index(h.length - i - 1)
23+
ji, _ := h.Index(h.length - j - 1)
24+
//we only swap the value, not the whole node
25+
ii.Value, ji.Value = ji.Value, ii.Value
26+
}
27+
28+
//Push pushes the element x onto the heap.
29+
func (h *Heap) Push(x interface{}) {
30+
node := NewListNode(x)
31+
h.Insert(node)
32+
}
33+
34+
//Pop removes the element with the highest priority from the heap and returns it.
35+
func (h *Heap) Pop() interface{} {
36+
if h.length == 0 {
37+
return nil
38+
}
39+
node, _ := h.Index(0)
40+
h.DeleteByIndex(0)
41+
return node.Value
42+
}
43+
44+
//NewHeap returns a new Heap
45+
func NewHeap(ismax bool) *Heap {
46+
return &Heap{
47+
LinkedList: NewLinkedList(),
48+
ismax: ismax,
49+
}
50+
}
51+
52+
//NewHeapNode returns a new HeapNode
53+
func NewHeapNode(value interface{}, priority int) *HeapNode {
54+
return &HeapNode{
55+
Value: value,
56+
Priority: priority,
57+
}
58+
}
59+
60+
//SetIsMax sets the ismax field of the Heap, it will make a max heap become a min heap, when ismax is false, it will be a min heap and when ismax is true, it will be a max heap. We will reinit the heap after setting it.
61+
func (h *Heap) SetIsMax(ismax bool) {
62+
h.ismax = ismax
63+
//reinit the heap
64+
heap.Init(h)
65+
}

heap_test.go

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package datastruct
2+
3+
import (
4+
"container/heap"
5+
"testing"
6+
)
7+
8+
//TestNewMaxHeapNode
9+
func TestNewHeapNode(t *testing.T) {
10+
node1 := NewHeapNode(1, 1)
11+
12+
if node1.Value != 1 || node1.Priority != 1 {
13+
t.Errorf("HeapNode: NewHeapNode error, it should be \" node1.Value == 1 && node1.Priority == 1\"")
14+
}
15+
}
16+
17+
//TestNewMaxHeap
18+
func TestNewMaxHeap(t *testing.T) {
19+
heap := NewHeap(true)
20+
21+
if heap.length != 0 {
22+
t.Errorf("Heap: NewMaxHeap error, it should be \" heap.length == 0\"")
23+
}
24+
}
25+
26+
//TestHeap
27+
func TestHeap(t *testing.T) {
28+
h := NewHeap(true)
29+
heap.Init(h)
30+
31+
heap.Push(h, &HeapNode{Value: 3, Priority: 3})
32+
heap.Push(h, &HeapNode{Value: 2, Priority: 2})
33+
heap.Push(h, &HeapNode{Value: 1, Priority: 1})
34+
heap.Push(h, &HeapNode{Value: 4, Priority: 4})
35+
heap.Push(h, &HeapNode{Value: 5, Priority: 5})
36+
heap.Push(h, &HeapNode{Value: 6, Priority: 6})
37+
38+
if h.length != 6 {
39+
t.Errorf("Heap: MaxHeap error, it should be \" h.length == 6\" but got %d", h.length)
40+
}
41+
42+
v := heap.Pop(h).(*HeapNode).Value
43+
if v != 6 {
44+
t.Errorf("Heap: MaxHeap error, it should be \" h.Pop().(*HeapNode).Value == 6\" but got %d", v)
45+
}
46+
47+
h.SetIsMax(false)
48+
v = heap.Pop(h).(*HeapNode).Value
49+
if v != 1 {
50+
t.Errorf("Heap: MinHeap error, it should be \" h.Pop().(*HeapNode).Value == 1\" but got %d", v)
51+
}
52+
53+
}
54+
55+
//TestHeapReversed
56+
func TestHeapReversed(t *testing.T) {
57+
h := NewHeap(true)
58+
heap.Init(h)
59+
60+
heap.Push(h, &HeapNode{Value: 1, Priority: 4})
61+
heap.Push(h, &HeapNode{Value: 2, Priority: 3})
62+
heap.Push(h, &HeapNode{Value: 3, Priority: 2})
63+
heap.Push(h, &HeapNode{Value: 4, Priority: 1})
64+
65+
if h.length != 4 {
66+
t.Errorf("Heap: MaxHeap error, it should be \" h.length == 5\" but got %d", h.length)
67+
}
68+
69+
v := heap.Pop(h).(*HeapNode).Value
70+
if v != 1 {
71+
t.Errorf("Heap: MaxHeap error, it should be \" h.Pop().(*HeapNode).Value == 1\" but got %d", v)
72+
}
73+
74+
h.SetIsMax(false)
75+
v = heap.Pop(h).(*HeapNode).Value
76+
if v != 4 {
77+
t.Errorf("Heap: MinHeap error, it should be \" h.Pop().(*HeapNode).Value == 4\" but got %d", v)
78+
}
79+
}

linkedlist.go

+12
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,18 @@ func (ll *LinkedList) InsertAt(node *ListNode, index int) error {
6868
return nil
6969
}
7070

71+
//Pop will return the first node and delete it from the list
72+
func (ll *LinkedList) Pop() (*ListNode, error) {
73+
if ll.length == 0 {
74+
return nil, errors.New("No Node")
75+
}
76+
tmpNode := ll.Head
77+
ll.Head = ll.Head.Next
78+
tmpNode.Next = nil
79+
ll.length--
80+
return tmpNode, nil
81+
}
82+
7183
func (ll *LinkedList) String() string {
7284
buf := bytes.NewBuffer([]byte{})
7385
tmpNode := ll.Head

linklist_test.go

+28
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,34 @@ func TestLinkedListIndex(t *testing.T) {
111111
}
112112
}
113113

114+
//TestLinkedListPop
115+
func TestLinkedListPop(t *testing.T) {
116+
var node1 = &ListNode{
117+
Next: nil,
118+
Value: 1,
119+
}
120+
var node2 = &ListNode{
121+
Next: node1,
122+
Value: 2,
123+
}
124+
var node3 = &ListNode{
125+
Next: node2,
126+
Value: 3,
127+
}
128+
ll := NewLinkedList()
129+
ll.Insert(node1)
130+
ll.Insert(node2)
131+
ll.Insert(node3)
132+
133+
tNode, err := ll.Pop()
134+
if err != nil {
135+
t.Errorf("LinkedList: Pop error: %s", err)
136+
}
137+
if tNode != node3 {
138+
t.Errorf("LinkedList: Pop error: it should be node3 but get %v", tNode)
139+
}
140+
}
141+
114142
func TestLinkedListDeleteByIndex(t *testing.T) {
115143
var node1 = &ListNode{
116144
Next: nil,

type.go

+12
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,15 @@ type Stack struct {
3131
type Queue struct {
3232
*LinkedList
3333
}
34+
35+
//Heap is a list which implements heap interface, we use ismax to indicate whether the heap is a max heap or min heap
36+
type Heap struct {
37+
*LinkedList
38+
ismax bool //true for max heap, false for min heap
39+
}
40+
41+
//HeapNode is a node in Heap
42+
type HeapNode struct {
43+
Value interface{}
44+
Priority int
45+
}

0 commit comments

Comments
 (0)