Go语言实战案例-链表的实现与遍历

在数据结构的世界中,链表(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 实现节点与链表结构
  • • 实现链表的增删查遍操作
  • • 利用泛型与函数式回调提升代码通用性与可读性

链表是数据结构中的基础砖石,理解它对于掌握更复杂结构如栈、队列、哈希表乃至图都有极大帮助。


相关推荐
苏三说技术5 小时前
Claude Code从失控到起飞,只用了这些技巧
后端
长栎6 小时前
写 for 循环写了十年,你却从没用过迭代器模式最狠的那一面
后端
LiaCode6 小时前
Redis 在生产项目的使用
前端·后端
用户559822481226 小时前
Docker Compose Down 导致容器数据误删——ext4 日志恢复全记录
后端
LiaCode6 小时前
一天学完 redis 的爽翻版核心知识总结
前端·后端
大刚测试开发实战6 小时前
如何内网穿透访问本地私有化部署的TestHub
前端·后端·github
xiaodaoluanzha7 小时前
迄今為止,最簡單的編程語言 Nolang
前端·后端
Csvn7 小时前
Docker 容器管理入门 — 从镜像到容器编排
后端
用户762352425917 小时前
ShardingJDBC
后端
行者全栈架构师7 小时前
IDEA 中 Maven 项目的 15 个红色报错快速解决方法
java·后端