From e802a2e4e95ae8b6c5b0bc59c55adaa224d02d9f Mon Sep 17 00:00:00 2001 From: yumaojun03 <719118794@qq.com> Date: Sun, 8 Feb 2026 10:34:11 +0800 Subject: [PATCH] =?UTF-8?q?```=20feat(pointer):=20=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E5=8F=8C=E5=90=91=E9=93=BE=E8=A1=A8=E6=95=B0=E6=8D=AE=E7=BB=93?= =?UTF-8?q?=E6=9E=84=E5=92=8C=E5=9F=BA=E6=9C=AC=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 实现完整的双向链表功能,包括节点定义、链表结构体以及核心操作方法: - Append: 在链表末尾添加节点 - Length: 获取链表长度 - GetIndexNode: 根据索引获取节点 - GetAt: 根据索引获取值 - Insert: 在指定位置插入节点 - Remove: 删除指定位置节点 - Print: 打印链表内容 更新README文档,添加链表实现代码示例和说明,并优化drawio图表。 ``` --- day04/pointer/README.md | 161 ++++++++++++++++++++++++++++++++- day04/pointer/link_list.drawio | 30 ++++-- day04/pointer/main.go | 155 +++++++++++++++++++++++++++++++ 3 files changed, 336 insertions(+), 10 deletions(-) create mode 100644 day04/pointer/main.go diff --git a/day04/pointer/README.md b/day04/pointer/README.md index a114734..32aa3d1 100644 --- a/day04/pointer/README.md +++ b/day04/pointer/README.md @@ -13,4 +13,163 @@ func getPtr() *int { ![alt text](image.png) -## 作业: 实现链表节点和基本操作 \ No newline at end of file +## 作业: 实现链表节点和基本操作 + + +```go +package main + +import "fmt" + +type Node struct { + Value int + Previous *Node // 指向前一个节点 + Next *Node // 指向下一个节点 +} + +type LinkedList struct { + Head *Node +} + +// TODO: 实现以下方法 + +// Append 在链表末尾添加节点 +func (l *LinkedList) Append(value int) { + node := &Node{ + Value: value, + } + + if l.Head == nil { + l.Head = node + return + } + + // 遍历链表找到最后一个节点(没有下一个指向), 然后将新节点添加到末尾 + current := l.Head + for current.Next != nil { + current = current.Next + } + + current.Next = node + node.Previous = current +} + +func (l *LinkedList) Length() int { + count := 0 + + current := l.Head + for current.Next != nil { + count++ + current = current.Next + } + return count + 1 +} + +// GetAt 获取指定位置的值 +func (l *LinkedList) GetIndexNode(index int) *Node { + if index < 0 || index >= l.Length() { + return nil + } + + current := l.Head + for range index { + current = current.Next + } + + return current +} + +// GetAt 获取指定位置的值 +func (l *LinkedList) GetAt(index int) (int, bool) { + current := l.GetIndexNode(index) + if current == nil { + return 0, false + } + return current.Value, true +} + +// Insert 在指定位置插入节点 +func (l *LinkedList) Insert(index int, value int) bool { + node := &Node{ + Value: value, + } + + // 开始和结束之间的位置 + if index < 0 || index > l.Length() { + return false + } + + // // 插入到开头 + // if index == 0 { + // node.Next = l.Head + // l.Head = node + // return true + // } + + // // 找到索引的前置节点 + // current := l.Head + // for i := 0; i < index-1; i++ { + // current = current.Next + // } + + current := l.GetIndexNode(index - 1) + + // 将新节点插入到当前节点和下一个节点之间, + // 需要把原来的值 挪到后面, + node.Next = current.Next + // 把前面的值指向新的节点 + current.Next = node + return true +} + +// Remove 删除指定位置的节点 +func (l *LinkedList) Remove(index int) bool { + if index < 0 || index >= l.Length() { + return false + } + + // 删除开头的节点,后面的节点自动升级为新的头节点 + if index == 0 { + l.Head = l.Head.Next + return true + } + + current := l.GetIndexNode(index - 1) + + // 将前一个节点的Next指向要删除节点的下一个节点, 通过Next的Next 来跳过要删除的节点 + current.Next = current.Next.Next + return true +} + +// Print 打印整个链表 +func (l *LinkedList) Print() { + for current := l.Head; current != nil; current = current.Next { + fmt.Print(current.Value) + if current.Next != nil { + fmt.Print(" -> ") + } + } + fmt.Println() +} + +func main() { + list := &LinkedList{} + + list.Append(10) + list.Append(20) + list.Append(30) + list.Print() // 输出: 10 -> 20 -> 30 + + list.Insert(1, 15) + list.Print() // 输出: 10 -> 15 -> 20 -> 30 + + value, ok := list.GetAt(2) + fmt.Println("位置2的值:", value, ok) // 20 true + + list.Remove(1) + list.Print() // 输出: 10 -> 20 -> 30 + fmt.Println("链表长度:", list.Length()) + + fmt.Println(list.GetIndexNode(1).Previous.Value) +} +``` \ No newline at end of file diff --git a/day04/pointer/link_list.drawio b/day04/pointer/link_list.drawio index b2aaa0b..ea13a17 100644 --- a/day04/pointer/link_list.drawio +++ b/day04/pointer/link_list.drawio @@ -1,27 +1,39 @@ - + - + - + - + - - + + - - + + - + + + + + + + + + + + + + diff --git a/day04/pointer/main.go b/day04/pointer/main.go new file mode 100644 index 0000000..a16a6e3 --- /dev/null +++ b/day04/pointer/main.go @@ -0,0 +1,155 @@ +package main + +import "fmt" + +type Node struct { + Value int + Previous *Node // 指向前一个节点 + Next *Node // 指向下一个节点 +} + +type LinkedList struct { + Head *Node +} + +// TODO: 实现以下方法 + +// Append 在链表末尾添加节点 +func (l *LinkedList) Append(value int) { + node := &Node{ + Value: value, + } + + if l.Head == nil { + l.Head = node + return + } + + // 遍历链表找到最后一个节点(没有下一个指向), 然后将新节点添加到末尾 + current := l.Head + for current.Next != nil { + current = current.Next + } + + current.Next = node + node.Previous = current +} + +func (l *LinkedList) Length() int { + count := 0 + + current := l.Head + for current.Next != nil { + count++ + current = current.Next + } + return count + 1 +} + +// GetAt 获取指定位置的值 +func (l *LinkedList) GetIndexNode(index int) *Node { + if index < 0 || index >= l.Length() { + return nil + } + + current := l.Head + for range index { + current = current.Next + } + + return current +} + +// GetAt 获取指定位置的值 +func (l *LinkedList) GetAt(index int) (int, bool) { + current := l.GetIndexNode(index) + if current == nil { + return 0, false + } + return current.Value, true +} + +// Insert 在指定位置插入节点 +func (l *LinkedList) Insert(index int, value int) bool { + node := &Node{ + Value: value, + } + + // 开始和结束之间的位置 + if index < 0 || index > l.Length() { + return false + } + + // // 插入到开头 + // if index == 0 { + // node.Next = l.Head + // l.Head = node + // return true + // } + + // // 找到索引的前置节点 + // current := l.Head + // for i := 0; i < index-1; i++ { + // current = current.Next + // } + + current := l.GetIndexNode(index - 1) + + // 将新节点插入到当前节点和下一个节点之间, + // 需要把原来的值 挪到后面, + node.Next = current.Next + // 把前面的值指向新的节点 + current.Next = node + return true +} + +// Remove 删除指定位置的节点 +func (l *LinkedList) Remove(index int) bool { + if index < 0 || index >= l.Length() { + return false + } + + // 删除开头的节点,后面的节点自动升级为新的头节点 + if index == 0 { + l.Head = l.Head.Next + return true + } + + current := l.GetIndexNode(index - 1) + + // 将前一个节点的Next指向要删除节点的下一个节点, 通过Next的Next 来跳过要删除的节点 + current.Next = current.Next.Next + return true +} + +// Print 打印整个链表 +func (l *LinkedList) Print() { + for current := l.Head; current != nil; current = current.Next { + fmt.Print(current.Value) + if current.Next != nil { + fmt.Print(" -> ") + } + } + fmt.Println() +} + +func main() { + list := &LinkedList{} + + list.Append(10) + list.Append(20) + list.Append(30) + list.Print() // 输出: 10 -> 20 -> 30 + + list.Insert(1, 15) + list.Print() // 输出: 10 -> 15 -> 20 -> 30 + + value, ok := list.GetAt(2) + fmt.Println("位置2的值:", value, ok) // 20 true + + list.Remove(1) + list.Print() // 输出: 10 -> 20 -> 30 + fmt.Println("链表长度:", list.Length()) + + fmt.Println(list.GetIndexNode(1).Previous.Value) +}