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