在数据结构的世界中,链表(Linked List) 是一种经典的线性结构,它以灵活的插入与删除能力著称。链表不像数组那样需要连续的内存空间,而是通过节点指针连接形成一条"链"。
本篇我们将使用 Go 语言实现一个单向链表,并演示其基本操作,如添加、删除、查找和遍历。
一、链表简介
链表由多个节点(Node)组成,每个节点包含两部分:
- • 数据域(Data):存储实际数据
- • 指针域(Next):指向下一个节点的指针
链表根据连接方式可分为:
- • 单向链表(单链表)
- • 双向链表(双链表)
- • 循环链表(环形链表)
本篇我们聚焦单向链表的实现。
二、Go语言实现单向链表结构
1. 定义节点结构
r
package linkedlist
type Node[T any] struct {
Value T
Next *Node[T]
}
使用泛型 T
表示支持任意数据类型。
2. 定义链表结构
r
type LinkedList[T any] struct {
Head *Node[T]
}
链表只需维护一个 Head
指针,即链表的起始节点。
3. 添加节点(尾插法)
ini
func (l *LinkedList[T]) Append(value T) {
newNode := &Node[T]{Value: value}
if l.Head == nil {
l.Head = newNode
return
}
current := l.Head
for current.Next != nil {
current = current.Next
}
current.Next = newNode
}
4. 遍历链表
go
func (l *LinkedList[T]) Traverse(f func(T)) {
current := l.Head
for current != nil {
f(current.Value)
current = current.Next
}
}
将遍历逻辑抽象成接收回调函数的方式,方便打印或处理节点数据。
5. 删除指定值节点(仅删除首个匹配项)
go
func (l *LinkedList[T]) Delete(value T, equal func(a, b T) bool) bool {
if l.Head == nil {
return false
}
if equal(l.Head.Value, value) {
l.Head = l.Head.Next
return true
}
prev := l.Head
curr := l.Head.Next
for curr != nil {
if equal(curr.Value, value) {
prev.Next = curr.Next
return true
}
prev = curr
curr = curr.Next
}
return false
}
6. 查找节点
go
func (l *LinkedList[T]) Find(value T, equal func(a, b T) bool) *Node[T] {
current := l.Head
for current != nil {
if equal(current.Value, value) {
return current
}
current = current.Next
}
return nil
}
三、使用示例
go
package main
import (
"fmt"
"linkedlist"
)
func main() {
list := linkedlist.LinkedList[int]{}
list.Append(10)
list.Append(20)
list.Append(30)
fmt.Println("遍历链表:")
list.Traverse(func(v int) {
fmt.Println(v)
})
fmt.Println("查找元素 20:")
node := list.Find(20, func(a, b int) bool { return a == b })
if node != nil {
fmt.Println("找到节点:", node.Value)
}
fmt.Println("删除元素 10:")
ok := list.Delete(10, func(a, b int) bool { return a == b })
fmt.Println("删除成功?", ok)
fmt.Println("再次遍历链表:")
list.Traverse(func(v int) {
fmt.Println(v)
})
}
四、进阶建议
想进一步提升链表的功能?你可以尝试:
- • 实现 头插法 / 按位置插入
- • 实现 双向链表
- • 实现 环形链表 并检测环
- • 使用 接口封装 提供更统一的操作抽象
- • 在链表上实现 反转 、合并 、中间节点查找 等常见算法
五、总结
通过本篇文章,你应该掌握了:
- • 链表的基本概念与结构
- • 使用 Go 实现节点与链表结构
- • 实现链表的增删查遍操作
- • 利用泛型与函数式回调提升代码通用性与可读性
链表是数据结构中的基础砖石,理解它对于掌握更复杂结构如栈、队列、哈希表乃至图都有极大帮助。