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

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


相关推荐
SamsongSSS2 分钟前
《C++ Primer Plus》读书笔记 第二章 开始学习C++
c++·后端
9号达人4 分钟前
Java18 新特性详解与实践
java·后端·面试
苏琢玉5 分钟前
作为 PHP 开发者,我第一次用 Go 写了个桌面应用
node.js·go·php
我不是混子10 分钟前
java浮点数精度问题及解决方案
java·后端
karry_k14 分钟前
混合存储架构
后端
yunxi_0515 分钟前
我用 Elasticsearch 做 RAG 检索的一些“土经验”
后端·llm
JaguarJack19 分钟前
PHP 8.2 vs PHP 8.3 对比:新功能、性能提升和迁移技巧
后端·php
学历真的很重要26 分钟前
Claude Code 万字斜杠命令指南
后端·语言模型·面试·职场和发展·golang·ai编程
稻草猫.1 小时前
Java线程安全:volatile与wait/notify详解
java·后端·idea
IT_陈寒1 小时前
Vite 5年迭代揭秘:3个核心优化让你的项目构建速度提升200%
前端·人工智能·后端