From 07a359484b5bf1dd1afb3de73d2752eddb9ccb03 Mon Sep 17 00:00:00 2001 From: reanon <793584285@qq.com> Date: Fri, 25 Nov 2022 20:24:51 +0800 Subject: [PATCH] feat(go): support basic pkg --- codes/go/chapter_searching/linear_search.go | 35 +++++ .../chapter_searching/linear_search_test.go | 24 ++++ codes/go/chapter_tree/binary_search_tree.go | 20 +++ codes/go/chapter_tree/binary_tree.go | 23 ++++ codes/go/chapter_tree/binary_tree_test.go | 40 ++++++ codes/go/pkg/list_node.go | 59 ++++++++ codes/go/pkg/list_node_test.go | 16 +++ codes/go/pkg/tree_node.go | 127 ++++++++++++++++++ codes/go/pkg/tree_node_test.go | 15 +++ 9 files changed, 359 insertions(+) create mode 100644 codes/go/chapter_searching/linear_search.go create mode 100644 codes/go/chapter_searching/linear_search_test.go create mode 100644 codes/go/chapter_tree/binary_search_tree.go create mode 100644 codes/go/chapter_tree/binary_tree.go create mode 100644 codes/go/chapter_tree/binary_tree_test.go create mode 100644 codes/go/pkg/list_node.go create mode 100644 codes/go/pkg/list_node_test.go create mode 100644 codes/go/pkg/tree_node.go create mode 100644 codes/go/pkg/tree_node_test.go diff --git a/codes/go/chapter_searching/linear_search.go b/codes/go/chapter_searching/linear_search.go new file mode 100644 index 000000000..ee06debd8 --- /dev/null +++ b/codes/go/chapter_searching/linear_search.go @@ -0,0 +1,35 @@ +// File: linear_search.go +// Created Time: 2022-11-25 +// Author: Reanon (793584285@qq.com) + +package chapter_searching + +import ( + . "github.com/krahets/hello-algo/pkg" +) + +// linerSearchArray 线性查找(数组) +func linerSearchArray(nums []int, target int) int { + // 遍历数组 + for i := 0; i < len(nums); i++ { + if nums[i] == target { + // 找到目标元素,返回其索引 + return i + } + } + // 未找到目标元素,返回 -1 + return -1 +} + +// linerSearchLinkedList 线性查找(链表) +func linerSearchLinkedList(node *ListNode, target int) *ListNode { + // 遍历链表 + for node != nil { + if node.Val == target { + return node + } + node = node.Next + } + // 未找到目标元素,返回 nil + return nil +} diff --git a/codes/go/chapter_searching/linear_search_test.go b/codes/go/chapter_searching/linear_search_test.go new file mode 100644 index 000000000..7f4915883 --- /dev/null +++ b/codes/go/chapter_searching/linear_search_test.go @@ -0,0 +1,24 @@ +// File: linear_search_test.go +// Created Time: 2022-11-25 +// Author: Reanon (793584285@qq.com) + +package chapter_searching + +import ( + . "github.com/krahets/hello-algo/pkg" + "testing" +) + +func TestLinearSearch(t *testing.T) { + target := 3 + nums := []int{1, 5, 3, 2, 4, 7, 5, 9, 10, 8} + + // 在数组中执行线性查找 + index := linerSearchArray(nums, target) + t.Log("目标元素 3 的索引 = ", index) + + // 在链表中执行线性查找 + head := ArrayToLinkedListLinkedList(nums) + node := linerSearchLinkedList(head, target) + t.Log("目标结点值 3 的对应结点对象为 ", node) +} diff --git a/codes/go/chapter_tree/binary_search_tree.go b/codes/go/chapter_tree/binary_search_tree.go new file mode 100644 index 000000000..c21dc1444 --- /dev/null +++ b/codes/go/chapter_tree/binary_search_tree.go @@ -0,0 +1,20 @@ +// File: binary_search_tree.go +// Created Time: 2022-11-25 +// Author: Reanon (793584285@qq.com) + +package chapter_tree + +import ( + . "github.com/krahets/hello-algo/pkg" + "sort" +) + +type BinarySearchTree struct { + root *TreeNode +} + +func NewBinarySearchTree(nums []int) *BinarySearchTree { + // 排序数组 + sort.Ints(nums) + return nil +} diff --git a/codes/go/chapter_tree/binary_tree.go b/codes/go/chapter_tree/binary_tree.go new file mode 100644 index 000000000..72143cd9a --- /dev/null +++ b/codes/go/chapter_tree/binary_tree.go @@ -0,0 +1,23 @@ +// File: binary_tree.go +// Created Time: 2022-11-25 +// Author: Reanon (793584285@qq.com) + +package chapter_tree + +import ( + . "github.com/krahets/hello-algo/pkg" +) + +type BinaryTree struct { + root *TreeNode +} + +func NewBinaryTree(node *TreeNode) *BinaryTree { + return &BinaryTree{ + root: node, + } +} + +func (tree *BinaryTree) Print() { + PrintTree(tree.root) +} diff --git a/codes/go/chapter_tree/binary_tree_test.go b/codes/go/chapter_tree/binary_tree_test.go new file mode 100644 index 000000000..ee77edc31 --- /dev/null +++ b/codes/go/chapter_tree/binary_tree_test.go @@ -0,0 +1,40 @@ +// File: binary_tree_test.go +// Created Time: 2022-11-25 +// Author: Reanon (793584285@qq.com) + +package chapter_tree + +import ( + . "github.com/krahets/hello-algo/pkg" + "testing" +) + +func TestBinaryTree(t *testing.T) { + /* 初始化二叉树 */ + // 初始化节点 + n1 := NewTreeNode(1) + n2 := NewTreeNode(2) + n3 := NewTreeNode(3) + n4 := NewTreeNode(4) + n5 := NewTreeNode(5) + + tree := NewBinaryTree(n1) + n1.Left = n2 + n1.Right = n3 + n2.Left = n4 + n2.Right = n5 + t.Log("初始化二叉树") + tree.Print() + + /* 插入与删除结点 */ + p := NewTreeNode(0) + n1.Left = p + p.Left = n2 + t.Log("插入结点 P 后") + tree.Print() + + // 删除结点 + n1.Left = n2 + t.Log("删除结点 P 后") + tree.Print() +} diff --git a/codes/go/pkg/list_node.go b/codes/go/pkg/list_node.go new file mode 100644 index 000000000..f7be3ad04 --- /dev/null +++ b/codes/go/pkg/list_node.go @@ -0,0 +1,59 @@ +// File: list_node.go +// Created Time: 2022-11-25 +// Author: Reanon (793584285@qq.com) + +package pkg + +import ( + "fmt" + "strconv" + "strings" +) + +// ListNode Definition for a singly-linked list node +type ListNode struct { + Next *ListNode + Val int +} + +// NewListNode Generate a list node with an val +func NewListNode(v int) *ListNode { + return &ListNode{ + Next: nil, + Val: v, + } +} + +// ArrayToLinkedListLinkedList Generate a linked list with an array +func ArrayToLinkedListLinkedList(arr []int) *ListNode { + // dummy header of linked list + dummy := NewListNode(0) + node := dummy + for _, val := range arr { + node.Next = NewListNode(val) + node = node.Next + } + return dummy.Next +} + +// GetListNode Get a list node with specific value from a linked list +func GetListNode(node *ListNode, val int) *ListNode { + for node != nil && node.Val != val { + node = node.Next + } + return node +} + +// PrintLinkedList Print a linked list +func PrintLinkedList(node *ListNode) { + if node == nil { + return + } + var builder strings.Builder + for node.Next != nil { + builder.WriteString(strconv.Itoa(node.Val) + " -> ") + node = node.Next + } + builder.WriteString(strconv.Itoa(node.Val)) + fmt.Println(builder.String()) +} diff --git a/codes/go/pkg/list_node_test.go b/codes/go/pkg/list_node_test.go new file mode 100644 index 000000000..5eee93ce7 --- /dev/null +++ b/codes/go/pkg/list_node_test.go @@ -0,0 +1,16 @@ +// File: list_node_test.go +// Created Time: 2022-11-25 +// Author: Reanon (793584285@qq.com) + +package pkg + +import "testing" + +func TestListNode(t *testing.T) { + arr := []int{2, 3, 5, 6, 7} + head := ArrayToLinkedListLinkedList(arr) + + PrintLinkedList(head) + node := GetListNode(head, 5) + t.Log("Find node: ", node.Val) +} diff --git a/codes/go/pkg/tree_node.go b/codes/go/pkg/tree_node.go new file mode 100644 index 000000000..571dfac24 --- /dev/null +++ b/codes/go/pkg/tree_node.go @@ -0,0 +1,127 @@ +// File: tree_node.go +// Created Time: 2022-11-25 +// Author: Reanon (793584285@qq.com) + +package pkg + +import ( + "container/list" + "fmt" +) + +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +func NewTreeNode(v int) *TreeNode { + return &TreeNode{ + Left: nil, + Right: nil, + Val: v, + } +} + +// ArrayToTree Generate a binary tree with an array +func ArrayToTree(arr []int) *TreeNode { + if len(arr) <= 0 { + return nil + } + root := NewTreeNode(arr[0]) + // Let container.list as queue + queue := list.New() + queue.PushBack(root) + i := 1 + for queue.Len() > 0 { + // poll + node := queue.Remove(queue.Front()).(*TreeNode) + if i < len(arr) { + node.Left = NewTreeNode(arr[i]) + queue.PushBack(node.Left) + i++ + } + if i < len(arr) { + node.Right = NewTreeNode(arr[i]) + queue.PushBack(node.Right) + i++ + } + } + return root +} + +// TreeToArray Serialize a binary tree to a list +func TreeToArray(root *TreeNode) []int { + if root == nil { + return []int{} + } + arr := make([]int, 16) + queue := list.New() + queue.PushBack(root) + for queue.Len() > 0 { + node := queue.Remove(queue.Front()).(*TreeNode) + if node != nil { + arr = append(arr, node.Val) + queue.PushBack(node.Left) + queue.PushBack(node.Right) + } else { + arr = append(arr, -1) + } + } + return arr +} + +// PrintTree Print a binary tree +func PrintTree(root *TreeNode) { + PrintTreeHelper(root, nil, false) +} + +// PrintTreeHelper Help to print a binary tree, hide more details +// This tree printer is borrowed from TECHIE DELIGHT +// https://www.techiedelight.com/c-program-print-binary-tree/ +func PrintTreeHelper(root *TreeNode, prev *trunk, isLeft bool) { + if root == nil { + return + } + prevStr := " " + trunk := newTrunk(prev, prevStr) + PrintTreeHelper(root.Right, trunk, true) + if prev == nil { + trunk.str = "———" + } else if isLeft { + trunk.str = "/———" + prevStr = " |" + } else { + trunk.str = "\\———" + prev.str = prevStr + } + showTrunk(trunk) + fmt.Println(root.Val) + if prev != nil { + prev.str = prevStr + } + trunk.str = " |" + PrintTreeHelper(root.Left, trunk, false) +} + +// trunk Help to Print tree structure +type trunk struct { + prev *trunk + str string +} + +func newTrunk(prev *trunk, str string) *trunk { + return &trunk{ + prev: prev, + str: str, + } +} + +func showTrunk(t *trunk) { + if t == nil { + return + } + + showTrunk(t.prev) + fmt.Print(t.str) +} diff --git a/codes/go/pkg/tree_node_test.go b/codes/go/pkg/tree_node_test.go new file mode 100644 index 000000000..c761ecb83 --- /dev/null +++ b/codes/go/pkg/tree_node_test.go @@ -0,0 +1,15 @@ +// File: tree_node_test.go +// Created Time: 2022-11-25 +// Author: Reanon (793584285@qq.com) + +package pkg + +import "testing" + +func TestTreeNode(t *testing.T) { + arr := []int{2, 3, 5, 6, 7} + node := ArrayToTree(arr) + + // print tree + PrintTree(node) +}