From 32962fb7a14d143d36fece4bdc315af2eb50e4b2 Mon Sep 17 00:00:00 2001 From: reanon <793584285@qq.com> Date: Thu, 12 Jan 2023 20:32:06 +0800 Subject: [PATCH 1/6] feat(heap): add go codes --- codes/go/chapter_heap/heap.go | 46 ++++++++++ codes/go/chapter_heap/heap_test.go | 90 +++++++++++++++++++ codes/go/chapter_heap/my_heap.go | 139 +++++++++++++++++++++++++++++ codes/go/pkg/print_utils.go | 23 +++-- 4 files changed, 291 insertions(+), 7 deletions(-) create mode 100644 codes/go/chapter_heap/heap.go create mode 100644 codes/go/chapter_heap/heap_test.go create mode 100644 codes/go/chapter_heap/my_heap.go diff --git a/codes/go/chapter_heap/heap.go b/codes/go/chapter_heap/heap.go new file mode 100644 index 000000000..d28d2ba7e --- /dev/null +++ b/codes/go/chapter_heap/heap.go @@ -0,0 +1,46 @@ +// File: intHeap.go +// Created Time: 2023-01-12 +// Author: Reanon (793584285@qq.com) + +package chapter_heap + +// intHeap 是一个由整数组成的最大堆 +// 通过实现 heap.Interface 来构建堆 +type intHeap []any + +// Len sort.Interface 的方法 +func (h *intHeap) Len() int { + return len(*h) +} + +// Less sort.Interface 的方法 +func (h *intHeap) Less(i, j int) bool { + // 如果实现小顶堆,则需要调整为小于号 + return (*h)[i].(int) > (*h)[j].(int) +} + +// Swap sort.Interface 的方法 +func (h *intHeap) Swap(i, j int) { + (*h)[i], (*h)[j] = (*h)[j], (*h)[i] +} + +// Push heap.Interface 的方法 + +func (h *intHeap) Push(x any) { + // Push 和 Pop 使用 pointer receiver 作为参数 + // 因为它们不仅会对切片的内容进行调整,还会修改切片的长度。 + *h = append(*h, x.(int)) +} + +// Top 获取堆顶元素 +func (h *intHeap) Top() int { + return (*h)[0].(int) +} + +// Pop heap.Interface 的方法,实现弹出堆顶元素 +func (h *intHeap) Pop() any { + // 待出堆元素存放在最后 + last := (*h)[len(*h)-1] + *h = (*h)[:len(*h)-1] + return last +} diff --git a/codes/go/chapter_heap/heap_test.go b/codes/go/chapter_heap/heap_test.go new file mode 100644 index 000000000..db3844efa --- /dev/null +++ b/codes/go/chapter_heap/heap_test.go @@ -0,0 +1,90 @@ +// File: heap_test.go +// Created Time: 2023-01-12 +// Author: Reanon (793584285@qq.com) + +package chapter_heap + +import ( + "container/heap" + "fmt" + "testing" + + . "github.com/krahets/hello-algo/pkg" +) + +func testPush(h *intHeap, val int) { + // 调用 heap.Interface 的方法,来添加元素 + heap.Push(h, val) + fmt.Printf("\n元素 %d 入堆后 \n", val) + PrintHeap(*h) +} + +func testPop(h *intHeap) { + // 调用 heap.Interface 的方法,来移除元素 + val := heap.Pop(h) + fmt.Printf("\n堆顶元素 %d 出堆后 \n", val) + PrintHeap(*h) +} + +func TestHeap(t *testing.T) { + /* 初始化堆 */ + // 初始化大顶堆 + maxHeap := &intHeap{} + heap.Init(maxHeap) + /* 元素入堆 */ + testPush(maxHeap, 1) + testPush(maxHeap, 3) + testPush(maxHeap, 2) + testPush(maxHeap, 5) + testPush(maxHeap, 4) + + /* 获取堆顶元素 */ + top := maxHeap.Top() + fmt.Printf("堆顶元素为 %d\n", top) + + /* 堆顶元素出堆 */ + testPop(maxHeap) + testPop(maxHeap) + testPop(maxHeap) + testPop(maxHeap) + testPop(maxHeap) + + /* 获取堆大小 */ + size := len(*maxHeap) + fmt.Printf("堆元素数量为 %d\n", size) + + /* 判断堆是否为空 */ + isEmpty := len(*maxHeap) == 0 + fmt.Printf("堆是否为空 %t\n", isEmpty) +} + +func TestMyHeap(t *testing.T) { + /* 初始化堆 */ + // 初始化大顶堆 + maxHeap := newMaxHeap([]any{9, 8, 6, 6, 7, 5, 2, 1, 4, 3, 6, 2}) + fmt.Printf("输入数组并建堆后\n") + maxHeap.print() + + /* 获取堆顶元素 */ + peek := maxHeap.peek() + fmt.Printf("\n堆顶元素为 %d\n", peek) + + /* 元素入堆 */ + val := 7 + maxHeap.push(val) + fmt.Printf("\n元素 %d 入堆后\n", val) + maxHeap.print() + + /* 堆顶元素出堆 */ + peek = maxHeap.poll() + fmt.Printf("\n堆顶元素 %d 出堆后\n", peek) + maxHeap.print() + + /* 获取堆大小 */ + size := maxHeap.size() + fmt.Printf("\n堆元素数量为 %d\n", size) + + /* 判断堆是否为空 */ + isEmpty := maxHeap.isEmpty() + fmt.Printf("\n堆是否为空 %t\n", isEmpty) +} diff --git a/codes/go/chapter_heap/my_heap.go b/codes/go/chapter_heap/my_heap.go new file mode 100644 index 000000000..53e961210 --- /dev/null +++ b/codes/go/chapter_heap/my_heap.go @@ -0,0 +1,139 @@ +// File: my_heap.go +// Created Time: 2023-01-12 +// Author: Reanon (793584285@qq.com) + +package chapter_heap + +import ( + "fmt" + + . "github.com/krahets/hello-algo/pkg" +) + +type maxHeap struct { + // 使用切片而非数组,这样无需考虑扩容问题 + data []any +} + +/* 构造函数,建立空堆 */ +func newHeap() *maxHeap { + return &maxHeap{ + data: make([]any, 0), + } +} + +/* 构造函数,根据切片建堆 */ +func newMaxHeap(nums []any) *maxHeap { + // 所有元素入堆 + h := &maxHeap{data: nums} + for i := len(h.data) - 1; i >= 0; i-- { + // 堆化除叶结点以外的其他所有结点 + h.siftDown(i) + } + return h +} + +/* 获取左子结点索引 */ +func (h *maxHeap) left(i int) int { + return 2*i + 1 +} + +/* 获取右子结点索引 */ +func (h *maxHeap) right(i int) int { + return 2*i + 2 +} + +/* 获取父结点索引 */ +func (h *maxHeap) parent(i int) int { + // 向下整除 + return (i - 1) / 2 +} + +/* 交换元素 */ +func (h *maxHeap) swap(i, j int) { + h.data[i], h.data[j] = h.data[j], h.data[i] +} + +/* 获取堆大小 */ +func (h *maxHeap) size() int { + return len(h.data) +} + +/* 判断堆是否为空 */ +func (h *maxHeap) isEmpty() bool { + return len(h.data) == 0 +} + +/* 访问堆顶元素 */ +func (h *maxHeap) peek() any { + return h.data[0] +} + +/* 元素入堆 */ +func (h *maxHeap) push(val any) { + // 添加结点 + h.data = append(h.data, val) + // 从底至顶堆化 + h.siftUp(len(h.data) - 1) +} + +/* 元素出堆 */ +func (h *maxHeap) poll() any { + // 判空处理 + if h.isEmpty() { + fmt.Println("error") + } + // 交换根结点与最右叶结点(即交换首元素与尾元素) + h.swap(0, h.size()-1) + // 删除结点 + val := h.data[len(h.data)-1] + h.data = h.data[:len(h.data)-1] + // 从顶至底堆化 + h.siftDown(0) + + // 返回堆顶元素 + return val +} + +/* 从结点 i 开始,从顶至底堆化 */ +func (h *maxHeap) siftDown(i int) { + for true { + // 判断结点 i, l, r 中值最大的结点,记为 max + l, r, max := h.left(i), h.right(i), i + if l < h.size() && h.data[l].(int) > h.data[max].(int) { + max = l + } + if r < h.size() && h.data[r].(int) > h.data[max].(int) { + max = r + } + // 若结点 i 最大或索引 l, r 越界,则无需继续堆化,跳出 + if max == i { + break + } + // 交换两结点 + h.swap(i, max) + // 循环向下堆化 + i = max + } +} + +/* 从结点 i 开始,从底至顶堆化 */ +func (h *maxHeap) siftUp(i int) { + for true { + // 获取结点 i 的父结点 + p := h.parent(i) + // 当“越过根结点”或“结点无需修复”时,结束堆化 + if p < 0 || h.data[i].(int) <= h.data[p].(int) { + break + } + // 交换两结点 + h.swap(i, p) + // 循环向上堆化 + i = p + } +} + +/* 打印堆(二叉树) */ +func (h *maxHeap) print() { + PrintHeap(h.data) +} diff --git a/codes/go/pkg/print_utils.go b/codes/go/pkg/print_utils.go index 575ab6b94..d65ebba1d 100644 --- a/codes/go/pkg/print_utils.go +++ b/codes/go/pkg/print_utils.go @@ -29,6 +29,22 @@ func PrintList(list *list.List) { fmt.Print(e.Value, "]\n") } +// PrintMap Print a hash map +func PrintMap[K comparable, V any](m map[K]V) { + for key, value := range m { + fmt.Println(key, "->", value) + } +} + +// PrintHeap Print a heap +func PrintHeap(h []any) { + fmt.Printf("堆的数组表示:") + fmt.Printf("%v", h) + fmt.Printf("\n堆的树状表示:\n") + root := ArrToTree(h) + PrintTree(root) +} + // PrintLinkedList Print a linked list func PrintLinkedList(node *ListNode) { if node == nil { @@ -97,10 +113,3 @@ func showTrunk(t *trunk) { showTrunk(t.prev) fmt.Print(t.str) } - -// PrintMap Print a hash map -func PrintMap[K comparable, V any](m map[K]V) { - for key, value := range m { - fmt.Println(key, "->", value) - } -} From 79d51e36913eac600ace5afc0b4b6fe9e52c49ef Mon Sep 17 00:00:00 2001 From: reanon <793584285@qq.com> Date: Thu, 12 Jan 2023 20:47:11 +0800 Subject: [PATCH 2/6] fix(heap): fix go code --- codes/go/chapter_heap/heap.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/codes/go/chapter_heap/heap.go b/codes/go/chapter_heap/heap.go index d28d2ba7e..a2c2eefef 100644 --- a/codes/go/chapter_heap/heap.go +++ b/codes/go/chapter_heap/heap.go @@ -4,9 +4,9 @@ package chapter_heap -// intHeap 是一个由整数组成的最大堆 +// intHeap 是一个由整数组成的堆 // 通过实现 heap.Interface 来构建堆 -type intHeap []any +type intHeap []int // Len sort.Interface 的方法 func (h *intHeap) Len() int { @@ -16,7 +16,7 @@ func (h *intHeap) Len() int { // Less sort.Interface 的方法 func (h *intHeap) Less(i, j int) bool { // 如果实现小顶堆,则需要调整为小于号 - return (*h)[i].(int) > (*h)[j].(int) + return (*h)[i] > (*h)[j] } // Swap sort.Interface 的方法 @@ -34,11 +34,11 @@ func (h *intHeap) Push(x any) { // Top 获取堆顶元素 func (h *intHeap) Top() int { - return (*h)[0].(int) + return (*h)[0] } // Pop heap.Interface 的方法,实现弹出堆顶元素 -func (h *intHeap) Pop() any { +func (h *intHeap) Pop() int { // 待出堆元素存放在最后 last := (*h)[len(*h)-1] *h = (*h)[:len(*h)-1] From 8117a1d47d0e130003126959fe5c17b395a36427 Mon Sep 17 00:00:00 2001 From: reanon <793584285@qq.com> Date: Thu, 12 Jan 2023 20:58:39 +0800 Subject: [PATCH 3/6] fix(heap): fix go code --- codes/go/chapter_heap/heap.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/codes/go/chapter_heap/heap.go b/codes/go/chapter_heap/heap.go index a2c2eefef..4a5b0c436 100644 --- a/codes/go/chapter_heap/heap.go +++ b/codes/go/chapter_heap/heap.go @@ -6,7 +6,7 @@ package chapter_heap // intHeap 是一个由整数组成的堆 // 通过实现 heap.Interface 来构建堆 -type intHeap []int +type intHeap []any // Len sort.Interface 的方法 func (h *intHeap) Len() int { @@ -16,7 +16,7 @@ func (h *intHeap) Len() int { // Less sort.Interface 的方法 func (h *intHeap) Less(i, j int) bool { // 如果实现小顶堆,则需要调整为小于号 - return (*h)[i] > (*h)[j] + return (*h)[i].(int) > (*h)[j].(int) } // Swap sort.Interface 的方法 @@ -33,12 +33,12 @@ func (h *intHeap) Push(x any) { } // Top 获取堆顶元素 -func (h *intHeap) Top() int { +func (h *intHeap) Top() any { return (*h)[0] } // Pop heap.Interface 的方法,实现弹出堆顶元素 -func (h *intHeap) Pop() int { +func (h *intHeap) Pop() any { // 待出堆元素存放在最后 last := (*h)[len(*h)-1] *h = (*h)[:len(*h)-1] From 264a2ab6bca636b299d045d61be5d75f626c7517 Mon Sep 17 00:00:00 2001 From: reanon <793584285@qq.com> Date: Fri, 13 Jan 2023 10:25:25 +0800 Subject: [PATCH 4/6] docs(heap): add go codes --- codes/go/chapter_heap/heap.go | 35 ++++---- codes/go/chapter_heap/my_heap.go | 32 +++---- docs/chapter_heap/heap.md | 139 ++++++++++++++++++++++++++++++- 3 files changed, 171 insertions(+), 35 deletions(-) diff --git a/codes/go/chapter_heap/heap.go b/codes/go/chapter_heap/heap.go index 4a5b0c436..5f846ced4 100644 --- a/codes/go/chapter_heap/heap.go +++ b/codes/go/chapter_heap/heap.go @@ -4,10 +4,25 @@ package chapter_heap -// intHeap 是一个由整数组成的堆 -// 通过实现 heap.Interface 来构建堆 +// Go 语言中可以通过实现 heap.Interface 来构建整数大顶堆 +// 实现 heap.Interface 需要同时实现 sort.Interface type intHeap []any +// Push heap.Interface 的方法,实现推入元素到堆 +func (h *intHeap) Push(x any) { + // Push 和 Pop 使用 pointer receiver 作为参数 + // 因为它们不仅会对切片的内容进行调整,还会修改切片的长度。 + *h = append(*h, x.(int)) +} + +// Pop heap.Interface 的方法,实现弹出堆顶元素 +func (h *intHeap) Pop() any { + // 待出堆元素存放在最后 + last := (*h)[len(*h)-1] + *h = (*h)[:len(*h)-1] + return last +} + // Len sort.Interface 的方法 func (h *intHeap) Len() int { return len(*h) @@ -24,23 +39,7 @@ func (h *intHeap) Swap(i, j int) { (*h)[i], (*h)[j] = (*h)[j], (*h)[i] } -// Push heap.Interface 的方法 - -func (h *intHeap) Push(x any) { - // Push 和 Pop 使用 pointer receiver 作为参数 - // 因为它们不仅会对切片的内容进行调整,还会修改切片的长度。 - *h = append(*h, x.(int)) -} - // Top 获取堆顶元素 func (h *intHeap) Top() any { return (*h)[0] } - -// Pop heap.Interface 的方法,实现弹出堆顶元素 -func (h *intHeap) Pop() any { - // 待出堆元素存放在最后 - last := (*h)[len(*h)-1] - *h = (*h)[:len(*h)-1] - return last -} diff --git a/codes/go/chapter_heap/my_heap.go b/codes/go/chapter_heap/my_heap.go index 53e961210..0b3d0a3b1 100644 --- a/codes/go/chapter_heap/my_heap.go +++ b/codes/go/chapter_heap/my_heap.go @@ -77,6 +77,22 @@ func (h *maxHeap) push(val any) { h.siftUp(len(h.data) - 1) } +/* 从结点 i 开始,从底至顶堆化 */ +func (h *maxHeap) siftUp(i int) { + for true { + // 获取结点 i 的父结点 + p := h.parent(i) + // 当“越过根结点”或“结点无需修复”时,结束堆化 + if p < 0 || h.data[i].(int) <= h.data[p].(int) { + break + } + // 交换两结点 + h.swap(i, p) + // 循环向上堆化 + i = p + } +} + /* 元素出堆 */ func (h *maxHeap) poll() any { // 判空处理 @@ -117,22 +133,6 @@ func (h *maxHeap) siftDown(i int) { } } -/* 从结点 i 开始,从底至顶堆化 */ -func (h *maxHeap) siftUp(i int) { - for true { - // 获取结点 i 的父结点 - p := h.parent(i) - // 当“越过根结点”或“结点无需修复”时,结束堆化 - if p < 0 || h.data[i].(int) <= h.data[p].(int) { - break - } - // 交换两结点 - h.swap(i, p) - // 循环向上堆化 - i = p - } -} - /* 打印堆(二叉树) */ func (h *maxHeap) print() { PrintHeap(h.data) diff --git a/docs/chapter_heap/heap.md b/docs/chapter_heap/heap.md index 73f425ff7..91f7670bc 100644 --- a/docs/chapter_heap/heap.md +++ b/docs/chapter_heap/heap.md @@ -97,7 +97,45 @@ comments: true === "Go" ```go title="heap.go" + // Go 语言中可以通过实现 heap.Interface 来构建整数大顶堆 + // 实现 heap.Interface 需要同时实现 sort.Interface + type intHeap []any + + // Push heap.Interface 的方法,实现推入元素到堆 + func (h *intHeap) Push(x any) { + // Push 和 Pop 使用 pointer receiver 作为参数 + // 因为它们不仅会对切片的内容进行调整,还会修改切片的长度。 + *h = append(*h, x.(int)) + } + + // Pop heap.Interface 的方法,实现弹出堆顶元素 + func (h *intHeap) Pop() any { + // 待出堆元素存放在最后 + last := (*h)[len(*h)-1] + *h = (*h)[:len(*h)-1] + return last + } + + // Len sort.Interface 的方法 + func (h *intHeap) Len() int { + return len(*h) + } + + // Less sort.Interface 的方法 + func (h *intHeap) Less(i, j int) bool { + // 如果实现小顶堆,则需要调整为小于号 + return (*h)[i].(int) > (*h)[j].(int) + } + // Swap sort.Interface 的方法 + func (h *intHeap) Swap(i, j int) { + (*h)[i], (*h)[j] = (*h)[j], (*h)[i] + } + + // Top 获取堆顶元素 + func (h *intHeap) Top() any { + return (*h)[0] + } ``` === "JavaScript" @@ -188,7 +226,33 @@ comments: true === "Go" ```go title="my_heap.go" + type maxHeap struct { + // 使用切片而非数组,这样无需考虑扩容问题 + data []any + } + + /* 构造函数,建立空堆 */ + func newHeap() *maxHeap { + return &maxHeap{ + data: make([]any, 0), + } + } + /* 获取左子结点索引 */ + func (h *maxHeap) left(i int) int { + return 2*i + 1 + } + + /* 获取右子结点索引 */ + func (h *maxHeap) right(i int) int { + return 2*i + 2 + } + + /* 获取父结点索引 */ + func (h *maxHeap) parent(i int) int { + // 向下整除 + return (i - 1) / 2 + } ``` === "JavaScript" @@ -249,6 +313,10 @@ comments: true === "Go" ```go title="my_heap.go" + /* 访问堆顶元素 */ + func (h *maxHeap) peek() any { + return h.data[0] + } ``` @@ -350,7 +418,29 @@ comments: true === "Go" ```go title="my_heap.go" + /* 元素入堆 */ + func (h *maxHeap) push(val any) { + // 添加结点 + h.data = append(h.data, val) + // 从底至顶堆化 + h.siftUp(len(h.data) - 1) + } + /* 从结点 i 开始,从底至顶堆化 */ + func (h *maxHeap) siftUp(i int) { + for true { + // 获取结点 i 的父结点 + p := h.parent(i) + // 当“越过根结点”或“结点无需修复”时,结束堆化 + if p < 0 || h.data[i].(int) <= h.data[p].(int) { + break + } + // 交换两结点 + h.swap(i, p) + // 循环向上堆化 + i = p + } + } ``` === "JavaScript" @@ -477,7 +567,45 @@ comments: true === "Go" ```go title="my_heap.go" + /* 元素出堆 */ + func (h *maxHeap) poll() any { + // 判空处理 + if h.isEmpty() { + fmt.Println("error") + } + // 交换根结点与最右叶结点(即交换首元素与尾元素) + h.swap(0, h.size()-1) + // 删除结点 + val := h.data[len(h.data)-1] + h.data = h.data[:len(h.data)-1] + // 从顶至底堆化 + h.siftDown(0) + // 返回堆顶元素 + return val + } + + /* 从结点 i 开始,从顶至底堆化 */ + func (h *maxHeap) siftDown(i int) { + for true { + // 判断结点 i, l, r 中值最大的结点,记为 max + l, r, max := h.left(i), h.right(i), i + if l < h.size() && h.data[l].(int) > h.data[max].(int) { + max = l + } + if r < h.size() && h.data[r].(int) > h.data[max].(int) { + max = r + } + // 若结点 i 最大或索引 l, r 越界,则无需继续堆化,跳出 + if max == i { + break + } + // 交换两结点 + h.swap(i, max) + // 循环向下堆化 + i = max + } + } ``` === "JavaScript" @@ -545,7 +673,16 @@ comments: true === "Go" ```go title="my_heap.go" - + /* 构造函数,根据切片建堆 */ + func newMaxHeap(nums []any) *maxHeap { + // 所有元素入堆 + h := &maxHeap{data: nums} + for i := len(h.data) - 1; i >= 0; i-- { + // 堆化除叶结点以外的其他所有结点 + h.siftDown(i) + } + return h + } ``` === "JavaScript" From 3dcdd1c72dafdae44ab5e7bfdbc06918a3adff93 Mon Sep 17 00:00:00 2001 From: reanon <793584285@qq.com> Date: Fri, 13 Jan 2023 17:37:24 +0800 Subject: [PATCH 5/6] fix(heap): add go codes --- codes/go/chapter_heap/heap.go | 40 +++++++++++++++++++++++++++++++++++ docs/chapter_heap/heap.md | 36 ++++++++++++++++++++++++++++++- 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/codes/go/chapter_heap/heap.go b/codes/go/chapter_heap/heap.go index 5f846ced4..886ec20e8 100644 --- a/codes/go/chapter_heap/heap.go +++ b/codes/go/chapter_heap/heap.go @@ -4,6 +4,11 @@ package chapter_heap +import ( + "container/heap" + "fmt" +) + // Go 语言中可以通过实现 heap.Interface 来构建整数大顶堆 // 实现 heap.Interface 需要同时实现 sort.Interface type intHeap []any @@ -43,3 +48,38 @@ func (h *intHeap) Swap(i, j int) { func (h *intHeap) Top() any { return (*h)[0] } + +/* Driver Code */ +func main() { + /* 初始化堆 */ + // 初始化大顶堆 + maxHeap := &intHeap{} + heap.Init(maxHeap) + /* 元素入堆 */ + // 调用 heap.Interface 的方法,来添加元素 + heap.Push(maxHeap, 1) + heap.Push(maxHeap, 3) + heap.Push(maxHeap, 2) + heap.Push(maxHeap, 4) + heap.Push(maxHeap, 5) + + /* 获取堆顶元素 */ + top := maxHeap.Top() + fmt.Printf("堆顶元素为 %d\n", top) + + /* 堆顶元素出堆 */ + // 调用 heap.Interface 的方法,来移除元素 + heap.Pop(maxHeap) + heap.Pop(maxHeap) + heap.Pop(maxHeap) + heap.Pop(maxHeap) + heap.Pop(maxHeap) + + /* 获取堆大小 */ + size := len(*maxHeap) + fmt.Printf("堆元素数量为 %d\n", size) + + /* 判断堆是否为空 */ + isEmpty := len(*maxHeap) == 0 + fmt.Printf("堆是否为空 %t\n", isEmpty) +} diff --git a/docs/chapter_heap/heap.md b/docs/chapter_heap/heap.md index 91f7670bc..924993257 100644 --- a/docs/chapter_heap/heap.md +++ b/docs/chapter_heap/heap.md @@ -136,6 +136,41 @@ comments: true func (h *intHeap) Top() any { return (*h)[0] } + + /* Driver Code */ + func TestHeap(t *testing.T) { + /* 初始化堆 */ + // 初始化大顶堆 + maxHeap := &intHeap{} + heap.Init(maxHeap) + /* 元素入堆 */ + // 调用 heap.Interface 的方法,来添加元素 + heap.Push(maxHeap, 1) + heap.Push(maxHeap, 3) + heap.Push(maxHeap, 2) + heap.Push(maxHeap, 4) + heap.Push(maxHeap, 5) + + /* 获取堆顶元素 */ + top := maxHeap.Top() + fmt.Printf("堆顶元素为 %d\n", top) + + /* 堆顶元素出堆 */ + // 调用 heap.Interface 的方法,来移除元素 + heap.Pop(maxHeap) + heap.Pop(maxHeap) + heap.Pop(maxHeap) + heap.Pop(maxHeap) + heap.Pop(maxHeap) + + /* 获取堆大小 */ + size := len(*maxHeap) + fmt.Printf("堆元素数量为 %d\n", size) + + /* 判断堆是否为空 */ + isEmpty := len(*maxHeap) == 0 + fmt.Printf("堆是否为空 %t\n", isEmpty) + } ``` === "JavaScript" @@ -317,7 +352,6 @@ comments: true func (h *maxHeap) peek() any { return h.data[0] } - ``` === "JavaScript" From ec28b4ce7a3d4580422c58275329b3cd192b4bb1 Mon Sep 17 00:00:00 2001 From: reanon <793584285@qq.com> Date: Fri, 13 Jan 2023 17:40:20 +0800 Subject: [PATCH 6/6] fix(heap): add go codes --- codes/go/chapter_heap/heap.go | 40 ----------------------------------- docs/chapter_heap/heap.md | 2 +- 2 files changed, 1 insertion(+), 41 deletions(-) diff --git a/codes/go/chapter_heap/heap.go b/codes/go/chapter_heap/heap.go index 886ec20e8..5f846ced4 100644 --- a/codes/go/chapter_heap/heap.go +++ b/codes/go/chapter_heap/heap.go @@ -4,11 +4,6 @@ package chapter_heap -import ( - "container/heap" - "fmt" -) - // Go 语言中可以通过实现 heap.Interface 来构建整数大顶堆 // 实现 heap.Interface 需要同时实现 sort.Interface type intHeap []any @@ -48,38 +43,3 @@ func (h *intHeap) Swap(i, j int) { func (h *intHeap) Top() any { return (*h)[0] } - -/* Driver Code */ -func main() { - /* 初始化堆 */ - // 初始化大顶堆 - maxHeap := &intHeap{} - heap.Init(maxHeap) - /* 元素入堆 */ - // 调用 heap.Interface 的方法,来添加元素 - heap.Push(maxHeap, 1) - heap.Push(maxHeap, 3) - heap.Push(maxHeap, 2) - heap.Push(maxHeap, 4) - heap.Push(maxHeap, 5) - - /* 获取堆顶元素 */ - top := maxHeap.Top() - fmt.Printf("堆顶元素为 %d\n", top) - - /* 堆顶元素出堆 */ - // 调用 heap.Interface 的方法,来移除元素 - heap.Pop(maxHeap) - heap.Pop(maxHeap) - heap.Pop(maxHeap) - heap.Pop(maxHeap) - heap.Pop(maxHeap) - - /* 获取堆大小 */ - size := len(*maxHeap) - fmt.Printf("堆元素数量为 %d\n", size) - - /* 判断堆是否为空 */ - isEmpty := len(*maxHeap) == 0 - fmt.Printf("堆是否为空 %t\n", isEmpty) -} diff --git a/docs/chapter_heap/heap.md b/docs/chapter_heap/heap.md index 924993257..15d22e787 100644 --- a/docs/chapter_heap/heap.md +++ b/docs/chapter_heap/heap.md @@ -262,7 +262,7 @@ comments: true ```go title="my_heap.go" type maxHeap struct { - // 使用切片而非数组,这样无需考虑扩容问题 + // 使用切片而非数组,这样无需考虑扩容问题 data []any }