文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Go 语言结构体链表的基本操作

2024-04-02 19:55

关注

1. 什么是链表

2. 单项链表的基本操作

3. 使用 struct 定义单链表

struct 定义的三种形式,其中2和3都是返回结构体的指针

//定义
var stu Student

var stu *Student = new(Student)

var stu *Student = &Student {}

//调用
stu.Name   stu.Age    stu.Score
或
(*stu).Name	   (*stu).Age   (*stu).Score

定义一个单项链表
next 是指针类型的属性,指向 Student struct 类型数据,也就是下一个节点的数据类型

type Student struct {
	Name  string
	Age   int
	Score float32
	next  *Student
}

为链表赋值,并遍历链表中的每个节点

package main
import "fmt"
type Student struct {
	Name  string
	Age   int
	Score float32
	next  *Student		//存放下一个结构体的地址,用*直接指向下一个结构体
}
func main() {
	//头部结构体
	var head Student
	head.Name = "张三"
	head.Age = 28
	head.Score = 88
	//第二个结构体节点
	var stu1 Student
	stu1.Name = "李四"
	stu1.Age = 25
	stu1.Score = 100
	head.next = &stu1
	//第三个结构体节点
	var stu2 Student
	stu2.Name = "王五"
	stu2.Age = 18
	stu2.Score = 60
	stu1.next = &stu2
	Req(&head)
}
func Req(tmp *Student) {		//tmp指针是指向下一个结构体的地址,加*就是下一个结构体
	for tmp != nil {			//遍历输出链表中每个结构体,判断是否为空
		fmt.Println(*tmp)
		tmp = tmp.next			//tmp变更为下一个结构体地址
	}
}

//输出结果如下
{张三 28 88 0xc000114480}
{李四 25 100 0xc0001144b0}
{王五 18 60 <nil>}

4. 尾部添加节点方法一

package main
import (
	"fmt"
	"math/rand"
)
type Student struct {
	Name  string
	Age   int
	Score float32
	next  *Student
}
func main() {
	//头部结构体
	var head Student
	head.Name = "head"
	head.Age = 28
	head.Score = 88
	//第二个结构体节点
	var stu1 Student
	stu1.Name = "stu1"
	stu1.Age = 25
	stu1.Score = 100
	head.next = &stu1 //头部指向第一个结构体
	//第三个结构体节点
	var stu2 Student
	stu2.Name = "stu2"
	stu2.Age = 18
	stu2.Score = 60
	stu1.next = &stu2 //第一个结构体指向第二个结构体
	//第四个结构体节点
	var stu3 Student
	stu3.Name = "stu3"
	stu3.Age = 18
	stu3.Score = 80
	stu2.next = &stu3 //第二个结构体指向第三个结构体
	//声明变量
	var tail = &stu3
	for i := 4; i < 10; i++ {
		//定义节点
		var stu Student = Student{
			Name:  fmt.Sprintf("stu%d", i),
			Age:   rand.Intn(100),
			Score: rand.Float32() * 100,
		}
		//生产结构体串联
		tail.next = &stu
		tail = &stu
	}
	Req(&head)
}
func Req(tmp *Student) {
	for tmp != nil {
		fmt.Println(*tmp)
		tmp = tmp.next
	}
}

//输出结果如下
{head 28 88 0xc0001144b0}
{stu1 25 100 0xc0001144e0}
{stu2 18 60 0xc000114510}
{stu3 18 80 0xc000114540}
{stu4 81 94.05091 0xc000114570}
{stu5 47 43.77142 0xc0001145a0}
{stu6 81 68.682304 0xc0001145d0}
{stu7 25 15.651925 0xc000114600}
{stu8 56 30.091187 0xc000114630}
{stu9 94 81.36399 <nil>}

方法二,使用函数进行优化

package main
import (
	"fmt"
	"math/rand"
)
type Student struct {
	Name  string
	Age   int
	Score float32
	next  *Student
}
func main() {
	//头部结构体
	var head Student
	head.Name = "head"
	head.Age = 28
	head.Score = 88
	TailInsert(&head)
	Req(&head)
}
//循环遍历
func Req(tmp *Student) {
	for tmp != nil {
		fmt.Println(*tmp)
		tmp = tmp.next
	}
}
//添加结构体节点
func TailInsert(tail *Student) {
	for i := 0; i < 10; i++ {
		//定义节点
		var stu Student = Student{
			Name:  fmt.Sprintf("stu%d", i),
			Age:   rand.Intn(100),
			Score: rand.Float32() * 100,
		}
		//生产结构体串联
		tail.next = &stu	//指向下一个结构体
		tail = &stu			//把当前的结构体给tail,让其继续循环
	}
}

//输出结果如下
{head 28 88 0xc0001144b0}
{stu0 81 94.05091 0xc0001144e0}
{stu1 47 43.77142 0xc000114510}
{stu2 81 68.682304 0xc000114540}
{stu3 25 15.651925 0xc000114570}
{stu4 56 30.091187 0xc0001145a0}
{stu5 94 81.36399 0xc0001145d0}
{stu6 62 38.06572 0xc000114600}
{stu7 28 46.888985 0xc000114630}
{stu8 11 29.310184 0xc000114660}
{stu9 37 21.855305 <nil>}

5. 头部插入节点方法一

package main

import (
	"fmt"
	"math/rand"
)
type Student struct {
	Name  string
	Age   int
	Score float32
	next  *Student
}
func main() {
	//头部结构体
	var head Student
	head.Name = "head"
	head.Age = 28
	head.Score = 88
	//调用头部插入函数
	HeadInsert(&head)
	Req(HeadInsert(&head))
func Req(tmp *Student) {
	for tmp != nil {
		fmt.Println(*tmp)
		tmp = tmp.next
	}
func HeadInsert(p *Student) *Student {
	for i := 0; i < 10; i++ {
		var stu = Student{
			Name:  fmt.Sprintf("stu%d", i),
			Age:   rand.Intn(100),
			Score: rand.Float32() * 100,
		}
		//当前新节点指向head,因为head是下一个节点
		stu.next = p //指向下一个节点
		p = &stu     //把当前的结构体给tail,让其继续循环
	return p

//输出结果如下
{stu9 85 30.152267 0xc000094840}
{stu8 37 5.912065 0xc000094810}
{stu7 29 7.9453626 0xc0000947e0}
{stu6 87 60.72534 0xc0000947b0}
{stu5 41 2.8303082 0xc000094780}
{stu4 90 69.67192 0xc000094750}
{stu3 87 20.658266 0xc000094720}
{stu2 47 29.708258 0xc0000946f0}
{stu1 28 86.249146 0xc0000946c0}
{stu0 95 36.08714 0xc0000944b0}
{head 28 88 <nil>}

方法二

使用指针的指针

package main

import (
	"fmt"
	"math/rand"
)
type Student struct {
	Name  string
	Age   int
	Score float32
	next  *Student
}
func main() {
	//头部结构体
	var head *Student = &Student{}
	head.Name = "head"
	head.Age = 28
	head.Score = 88
	//调用头部插入函数
	HeadInsert(&head)
	Req(head)
func Req(tmp *Student) {
	for tmp != nil {
		fmt.Println(*tmp)
		tmp = tmp.next
	}
func HeadInsert(p **Student) {
	for i := 0; i < 10; i++ {
		var stu = Student{
			Name:  fmt.Sprintf("stu%d", i),
			Age:   rand.Intn(100),
			Score: rand.Float32() * 100,
		}
		//当前新节点指向head,因为head是下一个节点
		stu.next = *p //指向下一个节点
		*p = &stu     //把当前的结构体给tail,让其继续循环

//输出结果如下
{stu9 37 21.855305 0xc000114660}
{stu8 11 29.310184 0xc000114630}
{stu7 28 46.888985 0xc000114600}
{stu6 62 38.06572 0xc0001145d0}
{stu5 94 81.36399 0xc0001145a0}
{stu4 56 30.091187 0xc000114570}
{stu3 25 15.651925 0xc000114540}
{stu2 81 68.682304 0xc000114510}
{stu1 47 43.77142 0xc0001144e0}
{stu0 81 94.05091 0xc0001144b0}
{head 28 88 <nil>}

总结
如果想要外部的数据和函数处理结果进行同步,两种方法:
① 传参,传递指针
② return 进行值的返回

6. 指定节点后添加新节点

package main

import (
	"fmt"
	"math/rand"
)
type Student struct {
	Name  string
	Age   int
	Score float32
	next  *Student
}
func main() {
	//头部结构体
	var head *Student = &Student{} //定义指针类型
	head.Name = "head"
	head.Age = 28
	head.Score = 88
	//定义新的节点
	var newNode *Student = &Student{} //定义指针类型
	newNode.Name = "newNode"
	newNode.Age = 19
	newNode.Score = 78
	HeadInsert(&head)
	//指定位置插入函数
	Add(head, newNode)
	Req(head)
func Req(tmp *Student) {
	for tmp != nil {
		fmt.Println(*tmp)
		tmp = tmp.next
	}
func HeadInsert(p **Student) { //传入指针的指针
	for i := 0; i < 10; i++ {
		var stu = Student{
			Name:  fmt.Sprintf("stu%d", i),
			Age:   rand.Intn(100),
			Score: rand.Float32() * 100,
		}
		//当前新节点指向head,因为head是下一个节点
		stu.next = *p //指向下一个节点
		*p = &stu     //把当前的结构体给tail,让其继续循环
//p为当前节点,newnode为插入的节点
func Add(p *Student, newNode *Student) {
	for p != nil {
		if p.Name == "stu6" {
			//对接下一个节点
			newNode.next = p.next
			p.next = newNode
		//插入节点指向下一个节点
		p = p.next //p.next赋予给p,继续进行循环遍历

//输出结果如下
{stu9 37 21.855305 0xc0000c0660}
{stu8 11 29.310184 0xc0000c0630}
{stu7 28 46.888985 0xc0000c0600}
{stu6 62 38.06572 0xc0000c04b0}
{newNode 19 78 0xc0000c05d0}
{stu5 94 81.36399 0xc0000c05a0}
{stu4 56 30.091187 0xc0000c0570}
{stu3 25 15.651925 0xc0000c0540}
{stu2 81 68.682304 0xc0000c0510}
{stu1 47 43.77142 0xc0000c04e0}
{stu0 81 94.05091 0xc0000c0480}
{head 28 88 <nil>}

7. 删除节点

package main

import (
	"fmt"
	"math/rand"
)
type Student struct {
	Name  string
	Age   int
	Score float32
	next  *Student
}
func main() {
	//头部结构体
	var head *Student = &Student{} //定义指针类型
	head.Name = "head"
	head.Age = 28
	head.Score = 88
	//定义新的节点
	var newNode *Student = &Student{} //定义指针类型
	newNode.Name = "newNode"
	newNode.Age = 19
	newNode.Score = 78
	HeadInsert(&head)
	//指定位置插入函数
	Add(head, newNode)
	//删除节点
	del(head)
	Req(head)
func Req(tmp *Student) {
	for tmp != nil {
		fmt.Println(*tmp)
		tmp = tmp.next
	}
func HeadInsert(p **Student) { //传入指针的指针
	for i := 0; i < 10; i++ {
		var stu = Student{
			Name:  fmt.Sprintf("stu%d", i),
			Age:   rand.Intn(100),
			Score: rand.Float32() * 100,
		}
		//当前新节点指向head,因为head是下一个节点
		stu.next = *p //指向下一个节点
		*p = &stu     //把当前的结构体给tail,让其继续循环
//p为当前节点,newnode为插入的节点
func Add(p *Student, newNode *Student) {
	for p != nil {
		if p.Name == "stu6" {
			//对接下一个节点
			newNode.next = p.next
			p.next = newNode
		//插入节点指向下一个节点
		p = p.next //p.next赋予给p,继续进行循环遍历
//删除节点
func del(p *Student) {
	var prev *Student = p			//p=head   prev=head  ——》prev=p
		if p.Name == "newNode" {
			prev.next = p.next
			break
		prev = p			//进行平移,前节点赋值
		p = p.next			//后节点赋值
 

 //输出结果如下
 {stu9 37 21.855305 0xc0000c0660}
{stu8 11 29.310184 0xc0000c0630}
{stu7 28 46.888985 0xc0000c0600}
{stu6 62 38.06572 0xc0000c05d0}
{stu5 94 81.36399 0xc0000c05a0}
{stu4 56 30.091187 0xc0000c0570}
{stu3 25 15.651925 0xc0000c0540}
{stu2 81 68.682304 0xc0000c0510}
{stu1 47 43.77142 0xc0000c04e0}
{stu0 81 94.05091 0xc0000c0480}
{head 28 88 <nil>}

到此这篇关于Go 语言结构体链表的文章就介绍到这了,更多相关Go 语言结构体链表内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯