详解Golang中链表的创建和读取

 更新时间:2023年12月13日 16:19:17   作者:鳄梨阿龙  
这篇文章主要为大家详细介绍了Golang中链表的创建和读取的相关知识,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以跟随小编一起了解下

链表的相关知识

链表有时会具有头节点,头节点的指针指向第一个节点的地址,其本身的数据域可以根据自己的选择进行赋值

接下来我将以将int转换为链表为例进行演示,如果有什么地方可以改进,也希望路过大神能够指出

链表的创建

链表的结构定义一般如下,即由本身的数据和指向下一个节点的指针构成

type ListNode struct {
    Val  int
    Next *ListNode//不能直接赋值listnode,避免产生嵌套引用
}

链表的创建(每个节点存储一位数字),在创建的过程中 我们需要设置中间的可变节点,不然我们可能会丢失对链表的第一个节点的索引,以下的例子中我们就使用middle为中间节点;将head设置为头节点,并代表完整的链表

模拟方式建立

我们利用迭代的方法,只要还存在num,就更新创建一个新的节点

// 尝试建立有头节点的链表,关键在于赋值给middle.next
func CreateList(nums int) *ListNode {
	Head := new(ListNode) //这代表一整个链表,并通过这里的头节点进行标注,方便该链表的引用

	middle := Head //middle视作Head链表的中间节点,其一直改变

	for nums > 0 {
		middle.Next = &ListNode{Val: nums % 10}//头节点赋值方法
		fmt.Printf("middle.Val: %v\n", middle.Val)
		middle = middle.Next
		nums /= 10
	}
	return Head
}

链表的递归创建

// 递归建立链表
func RecurCreateList(nums int) *ListNode {
	//在递归时好像不需要单独保存头节点位置,后续的位置会递归存储在next中,不用考虑被覆盖的问题
	middle := new(ListNode) //建立头指针,其指针不变

	// 123%10=3
	// 12.3%10=2
	// 1.23%10=1

	// 120%10=0
	// 12 %10=2
	// 1.2%10=1

	if nums > 1 || nums%10 > 0 {
		middle.Val = nums % 10
		fmt.Printf("middle.Val: %v\n", middle.Val)

		if nums > 1 {
			nums /= 10
			middle.Next = RecurCreateList(nums)
		}

	}
	return middle
}

链表的读取

遍历读取

链表读取时我们需要根据是否具有头节点进行一定的调整,下面是使用遍历(迭代)进行创建的过程

// 尝试遍历读取链表
func ReadList(L ListNode) {
	middle := L //将头节点赋予这里的中间节点middle

	//循环读取链表的内容
	for middle.Next != nil {
		v := middle.Next.Val //由于我们这里判断的是本身节点是否为空,所以在输出时使用下一节点的值进行输出,避免错过某个值
		fmt.Printf("v: %v\n", v)
		// 	// fmt.Printf("L: %v\n", L)
		middle = *middle.Next
		// 	// fmt.Printf("L: %v\n", L)
	}
}

递归读取

下面为使用递归进行读取的方法

由于节点的定义过程中使用内嵌,在建立相关函数时都使用指针比较方便[ 虽然前面都没注意:( ],

// 尝试递归读取链表
func RecurReadList(L *ListNode) {

	fmt.Printf("L.Val: %v\n", L.Val) //打印出此节点中的Val

	//如果本结点的指针不为空,即还有下一个节点,继续读取
	if L.Next != nil {
		RecurReadList(L.Next) //将下个节点的指针传入
	}
	//如果运行到这里,说明指针为空,函数也就到此结束了
}

完整代码

package main

import (
	"fmt"
)

type ListNode struct {
	Val  int
	Next *ListNode
}

func main() {
	// l := CreateList(13)
	l := RecurCreateList(13)
	fmt.Printf("l: %v\n", *l)
	// ReadList(*l)
	RecurReadList(l)
	// RecurReadList(l.Next)
	// fmt.Println(l.Next.Val)
}

// 尝试建立有头节点的链表,关键在于赋值给middle.next
func CreateList(nums int) *ListNode {
	Head := new(ListNode) //这代表一整个链表,并通过这里的头节点进行标注,方便该链表的引用

	middle := Head //middle视作Head链表的中间节点,其一直改变

	for nums > 0 {
		middle.Next = &ListNode{Val: nums % 10} //头节点赋值方法
		fmt.Printf("middle.Val: %v\n", middle.Val)
		middle = middle.Next
		nums /= 10
	}
	return Head
}

// 递归建立链表
func RecurCreateList(nums int) *ListNode {
	//在递归时好像不需要单独保存头节点位置,后续的位置会递归存储在next中,不用考虑被覆盖的问题
	middle := new(ListNode) //建立头指针,其指针不变

	// 123%10=3
	// 12.3%10=2
	// 1.23%10=1

	// 120%10=0
	// 12 %10=2
	// 1.2%10=1

	if nums > 1 || nums%10 > 0 {
		middle.Val = nums % 10
		fmt.Printf("middle.Val: %v\n", middle.Val)

		if nums > 1 {
			nums /= 10
			middle.Next = RecurCreateList(nums)
		}

	}
	return middle
}

// 尝试遍历读取链表
func ReadList(L ListNode) {

	middle := L //将头节点赋予这里的中间节点middle

	//循环读取链表的内容
	for middle.Next != nil {
		v := middle.Next.Val //由于我们这里判断的是本身节点是否为空,所以在输出时使用下一节点的值进行输出,避免错过某个值
		fmt.Printf("v: %v\n", v)
		// 	// fmt.Printf("L: %v\n", L)
		middle = *middle.Next
		// 	// fmt.Printf("L: %v\n", L)
	}
}

// 尝试递归读取链表
func RecurReadList(L *ListNode) {

	fmt.Printf("L.Val: %v\n", L.Val) //打印出此节点中的Val

	//如果本结点的指针不为空,即还有下一个节点,继续读取
	if L.Next != nil {
		RecurReadList(L.Next) //将下个节点的指针传入
	}
	//如果运行到这里,说明指针为空,函数也就到此结束了
}

到此这篇关于详解Golang中链表的创建和读取的文章就介绍到这了,更多相关Go链表内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • go sync.Once实现高效单例模式详解

    go sync.Once实现高效单例模式详解

    这篇文章主要为大家介绍了go sync.Once实现高效单例模式详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • golang gorm 计算字段和获取sum()值的实现

    golang gorm 计算字段和获取sum()值的实现

    这篇文章主要介绍了golang gorm 计算字段和获取sum()值的实现操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • go-micro微服务JWT跨域认证问题

    go-micro微服务JWT跨域认证问题

    JWT 以 JSON 对象的形式安全传递信息。因为存在数字签名,因此所传递的信息是安全的,这篇文章主要介绍了go-micro微服务JWT跨域认证,需要的朋友可以参考下
    2023-01-01
  • Go实现整合Logrus实现日志打印

    Go实现整合Logrus实现日志打印

    这篇文章主要介绍了Go实现整合Logrus实现日志打印,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-07-07
  • golang中两个协程交替打印数字和字母的实现

    golang中两个协程交替打印数字和字母的实现

    这篇文章给大家介绍了golang中两个协程交替打印数字和字母的实现,文中通过代码示例讲解的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2024-01-01
  • 浅析Golang中闭包的创建与使用

    浅析Golang中闭包的创建与使用

    闭包是包括 Go 在内的编程语言的一项强大功能,通过闭包,您可以在函数中封装数据,并通过函数的返回值访问这些数据,本文将介绍Go 中闭包的基础知识,希望对大家有所帮助
    2023-11-11
  • Go语言并发模型的2种编程方案

    Go语言并发模型的2种编程方案

    这篇文章主要介绍了Go语言并发模型的2种编程方案,本文给出共享内存和通过通信的2种解决方案,并给出了实现代码,需要的朋友可以参考下
    2014-10-10
  • Golang中设置全局变量并在其他文件中使用

    Golang中设置全局变量并在其他文件中使用

    全局变量是被整个程序都可见的变量,通常用于存储程序中需要共享的数据,本文就来介绍一下Golang中设置全局变量并在其他文件中使用的方法,感兴趣的可以了解一下
    2024-01-01
  • 一文带你了解Golang中的WaitGroups

    一文带你了解Golang中的WaitGroups

    WaitGroups是同步你的goroutines的一种有效方式。这篇文章主要来和大家聊聊Golang中WaitGroups的使用,感兴趣的小伙伴可以跟随小编一起了解一下
    2023-03-03
  • 基于Go语言开发篇一个命令行进程监控工具

    基于Go语言开发篇一个命令行进程监控工具

    在生产和开发环境中,监控关键进程的存活与资源使用是非常常见的需求,本篇将开发一个轻量级的命令行进程监控工具,感兴趣的小伙伴可以了解下
    2025-09-09

最新评论