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

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


相关推荐
派大鑫wink37 分钟前
分享一些在Spring Boot中进行参数配置的最佳实践
java·spring boot·后端
想学习java初学者38 分钟前
SpringBoot整合MQTT多租户(优化版)
java·spring boot·后端
正经教主38 分钟前
【Trae+AI】和Trae学习搭建App_2.1:第3章·手搓后端基础框架Express
人工智能·后端·学习·express
感谢地心引力1 小时前
【AI】免费的代价?Google AI Studio 使用指南与 Cherry Studio + MCP 实战教程
人工智能·ai·google·chatgpt·gemini·mcp·cherry studio
云上漫步者1 小时前
深度实战:Rust交叉编译适配OpenHarmony PC——sys_locale完整适配案例
开发语言·后端·rust
invicinble1 小时前
关于springboot引入traceid来保障可观测型
java·spring boot·后端
IT_陈寒1 小时前
JavaScript性能优化:5个V8引擎隐藏技巧让你的代码提速50%
前端·人工智能·后端
快乐就去敲代码@!2 小时前
Boot Cache Star ⭐(高性能两级缓存系统)
spring boot·redis·后端·缓存·docker·压力测试
我命由我123452 小时前
Python Flask 开发 - Flask 路径参数类型(string、int、float、path、uuid)
服务器·开发语言·后端·python·flask·学习方法·python3.11
文心快码BaiduComate2 小时前
Comate强力赋能:「趣绘像素岛」从体验泥潭到高性能可用的蜕变之路
前端·后端·程序员