mirror of
				https://github.com/krahets/hello-algo.git
				synced 2025-11-04 14:18:20 +08:00 
			
		
		
		
	Add divide and conquer go code (#638)
* feat: Add Go code to binary search recursion under divide and conquer * style: Code comment standardization * style: modify function comment * fix: fixed error when the list is empty * Update print_utils.go * Delete print_utils_test.go * feat: add Go code to divide and conquer * Update build_tree.go * style: modify function name --------- Co-authored-by: Yudong Jin <krahets@163.com>
This commit is contained in:
		
							
								
								
									
										37
									
								
								codes/go/chapter_divide_and_conquer/build_tree.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								codes/go/chapter_divide_and_conquer/build_tree.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,37 @@
 | 
			
		||||
// File: build_tree.go
 | 
			
		||||
// Created Time: 2023-07-20
 | 
			
		||||
// Author: hongyun-robot (1836017030@qq.com)
 | 
			
		||||
 | 
			
		||||
package chapter_divide_and_conquer
 | 
			
		||||
 | 
			
		||||
import . "github.com/krahets/hello-algo/pkg"
 | 
			
		||||
 | 
			
		||||
/* 构建二叉树:分治 */
 | 
			
		||||
func dfsBuildTree(preorder, inorder []int, hmap map[int]int, i, l, r int) *TreeNode {
 | 
			
		||||
	// 子树区间为空时终止
 | 
			
		||||
	if r-l < 0 {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	// 初始化根节点
 | 
			
		||||
	root := NewTreeNode(preorder[i])
 | 
			
		||||
	// 查询 m ,从而划分左右子树
 | 
			
		||||
	m := hmap[preorder[i]]
 | 
			
		||||
	// 子问题:构建左子树
 | 
			
		||||
	root.Left = dfsBuildTree(preorder, inorder, hmap, i+1, l, m-1)
 | 
			
		||||
	// 子问题:构建右子树
 | 
			
		||||
	root.Right = dfsBuildTree(preorder, inorder, hmap, i+1+m-l, m+1, r)
 | 
			
		||||
	// 返回根节点
 | 
			
		||||
	return root
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 构建二叉树 */
 | 
			
		||||
func buildTree(preorder, inorder []int) *TreeNode {
 | 
			
		||||
	// 初始化哈希表,存储 inorder 元素到索引的映射
 | 
			
		||||
	hmap := make(map[int]int, len(inorder))
 | 
			
		||||
	for i := 0; i < len(inorder); i++ {
 | 
			
		||||
		hmap[inorder[i]] = i
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	root := dfsBuildTree(preorder, inorder, hmap, 0, 0, len(inorder)-1)
 | 
			
		||||
	return root
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								codes/go/chapter_divide_and_conquer/build_tree_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								codes/go/chapter_divide_and_conquer/build_tree_test.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,24 @@
 | 
			
		||||
// File: build_tree_test.go
 | 
			
		||||
// Created Time: 2023-07-20
 | 
			
		||||
// Author: hongyun-robot (1836017030@qq.com)
 | 
			
		||||
 | 
			
		||||
package chapter_divide_and_conquer
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	. "github.com/krahets/hello-algo/pkg"
 | 
			
		||||
	"testing"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestBuildTree(t *testing.T) {
 | 
			
		||||
	preorder := []int{3, 9, 2, 1, 7}
 | 
			
		||||
	inorder := []int{9, 3, 1, 2, 7}
 | 
			
		||||
	fmt.Print("前序遍历 = ")
 | 
			
		||||
	PrintSlice(preorder)
 | 
			
		||||
	fmt.Print("中序遍历 = ")
 | 
			
		||||
	PrintSlice(inorder)
 | 
			
		||||
 | 
			
		||||
	root := buildTree(preorder, inorder)
 | 
			
		||||
	fmt.Println("构建的二叉树为:")
 | 
			
		||||
	PrintTree(root)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										39
									
								
								codes/go/chapter_divide_and_conquer/hanota.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								codes/go/chapter_divide_and_conquer/hanota.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,39 @@
 | 
			
		||||
// File: hanota.go
 | 
			
		||||
// Created Time: 2023-07-21
 | 
			
		||||
// Author: hongyun-robot (1836017030@qq.com)
 | 
			
		||||
 | 
			
		||||
package chapter_divide_and_conquer
 | 
			
		||||
 | 
			
		||||
import "container/list"
 | 
			
		||||
 | 
			
		||||
/* 移动一个圆盘 */
 | 
			
		||||
func move(src, tar *list.List) {
 | 
			
		||||
	// 从 src 顶部拿出一个圆盘
 | 
			
		||||
	pan := src.Back()
 | 
			
		||||
	// 将圆盘放入 tar 顶部
 | 
			
		||||
	tar.PushBack(pan.Value)
 | 
			
		||||
	// 移除 src 顶部圆盘
 | 
			
		||||
	src.Remove(pan)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 求解汉诺塔:问题 f(i) */
 | 
			
		||||
func dfsHanota(i int, src, buf, tar *list.List) {
 | 
			
		||||
	// 若 src 只剩下一个圆盘,则直接将其移到 tar
 | 
			
		||||
	if i == 1 {
 | 
			
		||||
		move(src, tar)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	// 子问题 f(i-1) :将 src 顶部 i-1 个圆盘借助 tar 移到 buf
 | 
			
		||||
	dfsHanota(i-1, src, tar, buf)
 | 
			
		||||
	// 子问题 f(1) :将 src 剩余一个圆盘移到 tar
 | 
			
		||||
	move(src, tar)
 | 
			
		||||
	// 子问题 f(i-1) :将 buf 顶部 i-1 个圆盘借助 src 移到 tar
 | 
			
		||||
	dfsHanota(i-1, buf, src, tar)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 求解汉诺塔 */
 | 
			
		||||
func hanota(A, B, C *list.List) {
 | 
			
		||||
	n := A.Len()
 | 
			
		||||
	// 将 A 顶部 n 个圆盘借助 B 移到 C
 | 
			
		||||
	dfsHanota(n, A, B, C)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										39
									
								
								codes/go/chapter_divide_and_conquer/hanota_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								codes/go/chapter_divide_and_conquer/hanota_test.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,39 @@
 | 
			
		||||
// File: hanota_test.go
 | 
			
		||||
// Created Time: 2023-07-21
 | 
			
		||||
// Author: hongyun-robot (1836017030@qq.com)
 | 
			
		||||
 | 
			
		||||
package chapter_divide_and_conquer
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"container/list"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	. "github.com/krahets/hello-algo/pkg"
 | 
			
		||||
	"testing"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestHanota(t *testing.T) {
 | 
			
		||||
	// 列表尾部是柱子顶部
 | 
			
		||||
	A := list.New()
 | 
			
		||||
	for i := 5; i > 0; i-- {
 | 
			
		||||
		A.PushBack(i)
 | 
			
		||||
	}
 | 
			
		||||
	B := list.New()
 | 
			
		||||
	C := list.New()
 | 
			
		||||
	fmt.Println("初始状态下:")
 | 
			
		||||
	fmt.Print("A = ")
 | 
			
		||||
	PrintList(A)
 | 
			
		||||
	fmt.Print("B = ")
 | 
			
		||||
	PrintList(B)
 | 
			
		||||
	fmt.Print("C = ")
 | 
			
		||||
	PrintList(C)
 | 
			
		||||
 | 
			
		||||
	hanota(A, B, C)
 | 
			
		||||
 | 
			
		||||
	fmt.Println("圆盘移动完成后:")
 | 
			
		||||
	fmt.Print("A = ")
 | 
			
		||||
	PrintList(A)
 | 
			
		||||
	fmt.Print("B = ")
 | 
			
		||||
	PrintList(B)
 | 
			
		||||
	fmt.Print("C = ")
 | 
			
		||||
	PrintList(C)
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user