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

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


相关推荐
ZHOUPUYU几秒前
PHP性能分析与调优:从定位瓶颈到实战优化
开发语言·后端·html·php
稻草猫.5 分钟前
MyBatis-Plus高效开发全攻略
java·数据库·后端·spring·java-ee·mybatis·mybatis-plus
lars_lhuan11 分钟前
Go atomic
开发语言·后端·golang
人道领域17 分钟前
Day | 09 【苍穹外卖:订单售后业务】
java·数据库·后端
清汤饺子30 分钟前
搞懂 Cursor 后,我一行代码都不敲了《实战篇》
前端·javascript·后端
AntBlack40 分钟前
Ant-Browser : 发布一个开源免费的指纹浏览器 ,欢迎体验
后端·架构·go
楼田莉子1 小时前
C++高性能并发内存池:三种Cache的设计及其内存申请释放
c++·后端·链表·哈希算法·visual studio
短剑重铸之日1 小时前
《ShardingSphere解读》12 解析引擎:SQL 解析流程应该包括哪些核心阶段?(下)
数据库·后端·sql·架构·shardingsphere·分库分表
计算机学姐1 小时前
基于SpringBoot的网吧管理系统
java·spring boot·后端·spring·tomcat·intellij-idea·mybatis
摸鱼的春哥1 小时前
Agent教程21:知识图谱🕸,让AI🤖学会联想
前端·javascript·后端