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

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


相关推荐
uzong5 小时前
技术故障复盘模版
后端
GetcharZp6 小时前
基于 Dify + 通义千问的多模态大模型 搭建发票识别 Agent
后端·llm·agent
桦说编程6 小时前
Java 中如何创建不可变类型
java·后端·函数式编程
IT毕设实战小研6 小时前
基于Spring Boot 4s店车辆管理系统 租车管理系统 停车位管理系统 智慧车辆管理系统
java·开发语言·spring boot·后端·spring·毕业设计·课程设计
wyiyiyi6 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
阿华的代码王国7 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
Jimmy7 小时前
AI 代理是什么,其有助于我们实现更智能编程
前端·后端·ai编程
AntBlack8 小时前
不当韭菜V1.1 :增强能力 ,辅助构建自己的交易规则
后端·python·pyqt
bobz9659 小时前
pip install 已经不再安全
后端
寻月隐君9 小时前
硬核实战:从零到一,用 Rust 和 Axum 构建高性能聊天服务后端
后端·rust·github