详解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语言里面的闭包

    简单聊聊Go语言里面的闭包

    这篇文章主要为大家详细介绍了Go语言中闭包的原理与实现的相关资料,文中的示例代码讲解详细,对我们学习Go语言有一定帮助,需要的可以参考一下
    2022-11-11
  • golang守护进程用法示例

    golang守护进程用法示例

    这篇文章主要介绍了golang守护进程用法,结合实例形式分析了Go语言守护进程的具体实现与使用技巧,需要的朋友可以参考下
    2016-07-07
  • go build和go install的区别介绍

    go build和go install的区别介绍

    这篇文章主要介绍了go build和go install的区别介绍,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • 浅谈JWT在GO中的使用方法及原理

    浅谈JWT在GO中的使用方法及原理

    JWT是一种基于 JSON 的开放标准,用于在网络应用间传递声明,JWT被设计为可安全地将用户身份验证和授权数据作为 JSON 对象在各个应用程序之间传递,本文将详细给大家介绍JWT原理及在Go中的用法,需要的朋友可以参考下
    2023-05-05
  • Go中的条件语句Switch示例详解

    Go中的条件语句Switch示例详解

    Go的switch的基本功能和C、Java类似,switch 语句用于基于不同条件执行不同动作,每一个 case 分支都是唯一的,从上至下逐一测试,直到匹配为止,对Go条件语句Switch相关知识感兴趣的朋友一起看看吧
    2021-08-08
  • Go读写锁操作方法示例详解

    Go读写锁操作方法示例详解

    这篇文章主要为大家介绍了Go读写锁方法示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • Go语言定时器Timer和Ticker的使用与区别

    Go语言定时器Timer和Ticker的使用与区别

    在Go语言中内置的有两个定时器,Timer和Ticker,本文主要介绍了Go语言定时器Timer和Ticker的使用与区别,具有一定的参考价值,感兴趣的可以了解一下
    2024-07-07
  • Beego AutoRouter工作原理解析

    Beego AutoRouter工作原理解析

    这篇文章主要为大家介绍了Beego AutoRouter工作原理解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • Golang Mutex实现互斥的具体方法

    Golang Mutex实现互斥的具体方法

    Mutex是Golang常见的并发原语,在开发过程中经常使用到,本文主要介绍了Golang Mutex实现互斥的具体方法,具有一定的参考价值,感兴趣的可以了解一下
    2023-04-04
  • 基于Go+OpenCV实现人脸识别功能的详细示例

    基于Go+OpenCV实现人脸识别功能的详细示例

    OpenCV是一个强大的计算机视觉库,提供了丰富的图像处理和计算机视觉算法,本文将向你介绍在Mac上安装OpenCV的步骤,并演示如何使用Go的OpenCV绑定库进行人脸识别,需要的朋友可以参考下
    2023-07-07

最新评论