详解Go语言中单链表的使用

详解Go语言中单链表的使用

什么是单链表

单链表(Singly Linked List)是一种常见的数据结构之一,它由一串节点组成,每个节点包含两个部分:数据部分和指向下一个节点的指针部分。

单链表的头部节点称为头节点,尾部节点称为尾节点。尾节点的指针部分指向NULL。

Go语言中单链表的实现

在Go语言中实现单链表,我们可以定义一个结构体表示链表节点,代码如下:

type ListNode struct {
    Val  int         // 数据部分
    Next *ListNode   // 指向下一个节点的指针部分
}

我们可以定义单链表的头节点,然后使用头节点来对链表进行操作(添加、删除、查找等)。

type LinkedList struct {
    Head *ListNode   // 头节点
}

Go语言单链表常见操作

初始化一个单链表

我们可以定义一个构造函数进行初始化:

func NewLinkedList() *LinkedList {
    return &LinkedList{
        Head: &ListNode{Val: 0, Next: nil},
    }
}

在链表的末尾添加一个节点

我们可以先找到链表的尾部节点,然后在尾部节点的后面添加一个新的节点。代码如下:

func (list *LinkedList) AddAtTail(val int) {
    newNode := &ListNode{
        Val:  val,
        Next: nil,
    }
    // 找到尾部节点
    tail := list.Head
    for tail.Next != nil {
        tail = tail.Next
    }
    tail.Next = newNode
}

在链表的头部添加一个节点

我们可以先创建一个新的节点,然后将新节点的指针部分指向头节点的下一个节点,最后将头节点的指针部分指向新节点。代码如下:

func (list *LinkedList) AddAtHead(val int) {
    newNode := &ListNode{
        Val:  val,
        Next: nil,
    }
    newNode.Next = list.Head.Next
    list.Head.Next = newNode
}

在链表的第index个位置插入一个节点

我们可以先找到要插入节点的位置,然后创建新的节点,将新节点的指针部分指向原来位置上的节点,最后将前一个节点的指针部分指向新节点。代码如下:

func (list *LinkedList) AddAtIndex(index int, val int) {
    newNode := &ListNode{
        Val:  val,
        Next: nil,
    }
    // 找到要插入的位置
    prev := list.Head
    for i := 0; i < index && prev != nil; i++ {
        prev = prev.Next
    }
    if prev == nil {
        return
    }
    // 将新节点插入到链表中
    newNode.Next = prev.Next
    prev.Next = newNode
}

在链表中删除一个节点

我们可以先找到要删除节点的前一个节点,然后将其指针部分指向被删除节点的下一个节点。代码如下:

func (list *LinkedList) DeleteAtIndex(index int) {
    // 找到要删除的节点的前一个节点
    prev := list.Head
    for i := 0; i < index && prev != nil; i++ {
        prev = prev.Next
    }
    if prev == nil || prev.Next == nil {
        return
    }
    // 将前一个节点的指针部分指向下一个节点
    prev.Next = prev.Next.Next
}

示例说明

示例一

我们可以按照以下步骤在Go语言中使用单链表:

  1. 创建一个新的单链表

go
list := NewLinkedList()

  1. 在单链表中添加节点

go
list.AddAtTail(1)
list.AddAtTail(2)
list.AddAtTail(3)
list.AddAtIndex(1, 4)
list.AddAtHead(5)

  1. 删除一个节点

go
list.DeleteAtIndex(3)

最终单链表的结果为:5, 1, 4, 2

示例二

我们还可以使用单链表来实现LRU缓存淘汰算法,以下是实现代码:

type LRUCache struct {
    capacity    int
    linkedList  *LinkedList
    hashMap     map[int]*ListNode
}

func Constructor(capacity int) LRUCache {
    return LRUCache{
        capacity:   capacity,
        linkedList: NewLinkedList(),
        hashMap:    make(map[int]*ListNode),
    }
}

func (this *LRUCache) Get(key int) int {
    if _, ok := this.hashMap[key]; !ok {
        return -1
    }
    node := this.hashMap[key]
    this.linkedList.DeleteNode(node)
    this.linkedList.AddAtHead(node.Val)
    return node.Val
}

func (this *LRUCache) Put(key int, value int) {
    if _, ok := this.hashMap[key]; ok {
        node := this.hashMap[key]
        node.Val = value
        this.linkedList.DeleteNode(node)
        this.linkedList.AddAtHead(node.Val)
        return
    }
    if this.linkedList.Length() >= this.capacity {
        tail := this.linkedList.RemoveTail()
        delete(this.hashMap, tail.Val)
    }
    newNode := &ListNode{
        Val:  value,
        Next: nil,
    }
    this.linkedList.AddAtHead(value)
    this.hashMap[key] = this.linkedList.Head.Next
}

以上是Go语言中单链表的使用攻略,希望对你有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解Go语言中单链表的使用 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • 微信小程序:多张图片上传

    微信小程序:多张图片上传攻略 微信小程序中,可以使用 wx.chooseImage() 方法来选择并上传多张图片。以下是使用 wx.chooseImage() 方法的完整攻略: 步骤1:选择图片 首先,您需要使用 wx.chooseImage() 方法选择要上传的图片。以下是一个示例代码片段,演示如 wx.chooseImage() 方法选择图片: wx.c…

    other 2023年5月9日
    00
  • vue封装axios的几种方法

    下面是“Vue封装Axios的几种方法”的完整攻略: 1. 为什么要封装Axios 在Vue项目中,使用Axios发送请求已经成为了常态。但是如果每次请求都手动编写Axios的代码,将会极大地降低开发效率,并且还容易导致代码重复。因此,我们需要封装Axios的代码,统一管理请求。另外,通过封装,还可以添加统一的请求头、响应拦截器等功能,提高代码的可维护性和安…

    other 2023年6月25日
    00
  • vue中input标签上传本地文件或图片后获取完整路径的解决方法

    针对Vue中如何获取本地文件或图片的完整路径,下面是一份完整攻略: 问题阐述 在Vue中使用input标签上传本地文件或图片,常见的困难在于如何获取完整路径,以便实现相关功能。因为在浏览器架构下,为了保护用户隐私,直接获取文件路径的方法是无效的。 解决方法 方法一:使用URL.createObjectURL() URL.createObjectURL() 方…

    other 2023年6月27日
    00
  • mybatis存储无限长度的数据

    MyBatis 存储无限长度的数据 MyBatis 是一种流行的持久化框架,它在数据层面上提供了许多的功能和特性。在本文中,我们将探讨 MyBatis 是如何存储无限长度的数据的。 为什么需要存储无限长度的数据 在我们的应用程序中,有些数据的长度是不确定的,例如,一些用户的评论、博文和文章等,这些数据的长度往往不受限制。在这种情况下,如果我们使用 MySQL…

    其他 2023年3月29日
    00
  • Flash cs6类名的定义有什么规则? Flash的组成部分

    Flash cs6类名的定义规则: 类名必须以字母或下划线开头,后跟任意数量的字母、数字或下划线。类名不应包含空格或其他特殊字符。 类名应该具有描述性和可读性,以方便维护和理解代码。 如果类名包含多个单词,请使用大写字母分隔每个单词。例如,MyClass、MyAwesomeClass等。 Flash cs6的组成部分: 菜单栏和工具栏:Flash cs6的菜…

    other 2023年6月27日
    00
  • iqoo8pro怎么开启开发者模式?iqoo8pro开启开发者模式教程

    当您需要进行一些高级设置或开发调试时,开启开发者模式是必须的。在iQOO 8 Pro中也可以通过以下步骤来启用开发者模式: 打开“设置”应用程序。 向下滚动并点击“关于手机”。 点击“版本号”七次,系统将提示“开启开发者模式”。 返回上一屏幕,在“系统”下找到“开发者选项”,点击进入设置页面。 将“开发者选项”状态切换为“开启”。 以上是iQOO 8 Pro…

    other 2023年6月26日
    00
  • 辐射4 NMM安装framework失败问题的解决方法

    下面是详细的攻略: 问题描述 在安装辐射4 Nexus Mod Manager (NMM) 的时候,如果遇到了以下安装framework失败的错误: The installation of Microsoft .NET Framework 4.0 Full has failed. Memory error during installation. Pleas…

    other 2023年6月27日
    00
  • 使用useEffect模拟组件生命周期

    使用useEffect模拟组件生命周期是React Hooks的一个常见用法,它能够模拟类组件的componentDidMount、componentDidUpdate和componentWillUnmount等生命周期方法。 使用useEffect的第一个参数为回调函数,它会在组件挂载后执行(类似componentDidMount),并且也会在组件更新时执…

    other 2023年6月27日
    00
合作推广
合作推广
分享本页
返回顶部