diff --git a/codes/go/chapter_array_and_linkedlist/linked_list.go b/codes/go/chapter_array_and_linkedlist/linked_list.go new file mode 100644 index 00000000..3129a0ea --- /dev/null +++ b/codes/go/chapter_array_and_linkedlist/linked_list.go @@ -0,0 +1,105 @@ +// File: linked_list.go +// Created Time: 2022-12-29 +// Author: cathay (cathaycchen@gmail.com) + +package chapter_array_and_linkedlist + +import ( + "fmt" + "strconv" + "strings" +) + +/* 链表结点结构体 */ +type ListNode struct { + Val int // 结点值 + Next *ListNode // 指向下一结点的指针(引用) +} + +// NewListNode 构造函数,创建一个新的链表 +func NewListNode(val int) *ListNode { + return &ListNode{ + Val: val, + Next: nil, + } +} + +// 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()) +} + +/* 在链表的结点 n0 之后插入结点 P */ +func insertNode(n0 *ListNode, P *ListNode) { + n1 := n0.Next + n0.Next = P + P.Next = n1 +} + +/* 删除链表的结点 n0 之后的首个结点 */ +func removeNode(n0 *ListNode) { + if n0.Next == nil { + return + } + // n0 -> P -> n1 + P := n0.Next + n1 := P.Next + n0.Next = n1 +} + +/* 访问链表中索引为 index 的结点 */ +func access(head *ListNode, index int) *ListNode { + for i := 0; i < index; i++ { + head = head.Next + if head == nil { + return nil + } + } + return head +} + +/* 在链表中查找值为 target 的首个结点 */ +func findNode(head *ListNode, target int) int { + index := 0 + for head != nil { + if head.Val == target { + return index + } + head = head.Next + index++ + } + return -1 +} + +/* 双向链表结点结构体 */ +type DoublyListNode struct { + Val int // 结点值 + Next *DoublyListNode // 指向后继结点的指针(引用) + Prev *DoublyListNode // 指向前驱结点的指针(引用) +} + +// NewDoublyListNode 初始化 +func NewDoublyListNode(val int, nodes ...*DoublyListNode) *DoublyListNode { + var next, prev *DoublyListNode + length := len(nodes) + if length > 0 { + next = nodes[0] + } + if length > 1 { + prev = nodes[1] + } + return &DoublyListNode{ + Val: val, + Next: next, + Prev: prev, + } +} diff --git a/codes/go/chapter_array_and_linkedlist/linked_list_test.go b/codes/go/chapter_array_and_linkedlist/linked_list_test.go new file mode 100644 index 00000000..5deabff8 --- /dev/null +++ b/codes/go/chapter_array_and_linkedlist/linked_list_test.go @@ -0,0 +1,47 @@ +// File: linked_list_test.go +// Created Time: 2022-12-29 +// Author: cathay (cathaycchen@gmail.com) + +package chapter_array_and_linkedlist + +import ( + "fmt" + "testing" +) + +func TestLikedList(t *testing.T) { + /* 初始化链表 1 -> 3 -> 2 -> 5 -> 4 */ + // 初始化各个结点 + n0 := NewListNode(1) + n1 := NewListNode(3) + n2 := NewListNode(2) + n3 := NewListNode(5) + n4 := NewListNode(4) + + // 构建引用指向 + n0.Next = n1 + n1.Next = n2 + n2.Next = n3 + n3.Next = n4 + + fmt.Println("链表结构:") + PrintLinkedList(n0) + + P := NewListNode(6) + + /* 在链表的结点 n0 之后插入结点 P */ + insertNode(n0, P) + fmt.Println("在链表的结点 n0 之后插入结点 P 后,链表结构:") + PrintLinkedList(n0) + + /* 删除链表的结点 n0 之后的首个结点 */ + removeNode(n0) + fmt.Println("删除链表的结点 n0 之后的首个结点后,链表结构:") + PrintLinkedList(n0) + + /* 访问链表中索引为 index 的结点 */ + fmt.Println("访问链表中索引为 2 的结点:", access(n0, 2)) + + /* 在链表中查找值为 target 的首个结点 */ + fmt.Println("在链表中查找 5 的首个节点索引值:", findNode(n0, 5)) +} diff --git a/docs/chapter_array_and_linkedlist/linked_list.md b/docs/chapter_array_and_linkedlist/linked_list.md index 6ad1d565..83c8db64 100644 --- a/docs/chapter_array_and_linkedlist/linked_list.md +++ b/docs/chapter_array_and_linkedlist/linked_list.md @@ -51,7 +51,19 @@ comments: true === "Go" ```go title="" - + /* 链表结点结构体 */ + type ListNode struct { + Val int // 结点值 + Next *ListNode // 指向下一结点的指针(引用) + } + + // NewListNode 构造函数,创建一个新的链表 + func NewListNode(val int) *ListNode { + return &ListNode{ + Val: val, + Next: nil, + } + } ``` === "JavaScript" @@ -162,7 +174,19 @@ comments: true === "Go" ```go title="" + /* 初始化链表 1 -> 3 -> 2 -> 5 -> 4 */ + // 初始化各个结点 + n0 := NewListNode(1) + n1 := NewListNode(3) + n2 := NewListNode(2) + n3 := NewListNode(5) + n4 := NewListNode(4) + // 构建引用指向 + n0.Next = n1 + n1.Next = n2 + n2.Next = n3 + n3.Next = n4 ``` === "JavaScript" @@ -294,7 +318,23 @@ comments: true === "Go" ```go title="" + /* 在链表的结点 n0 之后插入结点 P */ + func insert(n0 *ListNode, P *ListNode) { + n1 := n0.Next + n0.Next = P + P.Next = n1 + } + /* 删除链表的结点 n0 之后的首个结点 */ + func removeNode(n0 *ListNode) { + if n0.Next == nil { + return + } + // n0 -> P -> n1 + P := n0.Next + n1 := P.Next + n0.Next = n1 + } ``` === "JavaScript" @@ -415,7 +455,16 @@ comments: true === "Go" ```go title="" - + /* 访问链表中索引为 index 的结点 */ + func access(head *ListNode, index int) *ListNode { + for i := 0; i < index; i++ { + head = head.Next + if head == nil { + return nil + } + } + return head + } ``` === "JavaScript" @@ -524,7 +573,18 @@ comments: true === "Go" ```go title="" - + /* 在链表中查找值为 target 的首个结点 */ + func find(head *ListNode, target int) int { + index := 0 + for head != nil { + if head.Val == target { + return index + } + head = head.Next + index++ + } + return -1 + } ``` === "JavaScript" @@ -631,7 +691,21 @@ comments: true === "Go" ```go title="" - + /* 双向链表结点结构体 */ + type DoublyListNode struct { + Val int // 结点值 + Next *DoublyListNode // 指向后继结点的指针(引用) + Prev *DoublyListNode // 指向前驱结点的指针(引用) + } + + // NewDoublyListNode 初始化 + func NewDoublyListNode(val int) *DoublyListNode { + return &DoublyListNode{ + Val: val, + Next: nil, + Prev: nil, + } + } ``` === "JavaScript"