go 链表操作
链表的特点和初始化
链表的特点
用一组任意的存储单元存储线性表的数据元素(这组存储单元可以是连续的,也可以是不连续的)
结点
结点(node)
数据域 => 存储元素信息
指针域 => 存储结点的直接后继,也称作指针或链
首元结点 是指链表中存储的第一个数据元素的结点
头结点 是在首元结点之前附设的一个结点,其指针域指向首元结点(非必须)
头指针 是指向链表中第一个结点的指针
单链表特点
- 每个结点中只包含一个指针域
- 单链表是非随机存取的存储结构,要取得第i个数据元素必须从头指针出发,顺链进行寻找,也称为顺序存取的存取结构
官方包链表操作
https://pkg.go.dev/container/list
手动实现单链表部分操作
// 实现单链表一些基础操作
package main
import (
"errors"
"fmt"
)
// 链表结构
type ListNode struct {
Data int
Next *ListNode
}
// 初始化链表头,下面所有操作都基于带头链表
func NewListNode() *ListNode {
return &ListNode{Next: nil}
}
// 获取链表长度
func (l *ListNode) Length() int {
len := 0
for l.Next != nil {
len++
l = l.Next
}
return len
}
// 插入节点
func (l *ListNode) InsertNode(d int) error {
newNode := new(ListNode)
newNode.Data = d
newNode.Next = l.Next
l.Next = newNode
return nil
}
// 删除节点
func (l *ListNode) DelNode(d int) {
if l == nil {
errors.New("Empty List!")
return
}
for l.Next != nil {
if l.Next.Data == d {
l.Next = l.Next.Next
// return 是否全部删除与d相同数据
}
l = l.Next
}
}
// 遍历单链表
func (l *ListNode) ListNode() {
for l.Next != nil {
fmt.Printf("%d", l.Next.Data)
l = l.Next
}
}
// 递归反转单链表
func ReverseList(pHead, node *ListNode) *ListNode {
if node.Next == nil {
pHead.Next = node
return node
}
if n := ReverseList(pHead, node.Next); n != nil {
n.Next = node
node.Next = nil
}
return node
}
// 遍历反转单链表
func (pHead *ListNode) ReverseListV2() {
pReverseHead := pHead
var pNode = pHead.Next
var pPrev *ListNode
for pNode != nil {
pNext := pNode.Next
if pNext == nil {
pReverseHead.Next = pNode
}
pNode.Next = pPrev
pPrev = pNode
pNode = pNext
}
return
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通