您的位置:首页 > 理论基础 > 数据结构算法

分享下最近使用golang模拟的链表数据结构

2020-04-07 19:00 645 查看

首先,我们知道链表的特性,分别有单线链表和双线链表,下面我用golang来模拟了一个单线链表

链表的添加,他其实分别是有头部插入法和尾部插入法的,我在代码中都写了这两个方法

结构体 Student 是必须要有一个指针,这个指针是指向下一个链表的,当然,如果是双向链表的话,这里还需要记录一个头部指针,也就是说这个结构体会有两个指针

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

 

一个小细节:在插入某一个节点,比如 a b c 三个节点,我需要插入一个d 在 a 和 b 之间,这时候遍历到b 之后再进行插入,不然你如果在a的时候就开始进行插入操作,那么你是获取不到b节点的尾部的

 

双向链表

 

 

完整的代码:

[code]package main

import (
"fmt"
"math/rand"
)

/*
链表的结构
*/
type Student struct {
Name  string
Age   int
Score float32
next  *Student
}

/*
尾部插入法
*/
func insertTail(p *Student) {
var tail = p // 初始化节点
for i := 0; i < 10; i++ {
stu := Student{
Name:  fmt.Sprintf("stu%d", i),
Age:   rand.Intn(100),
Score: rand.Float32() * 100,
}
tail.next = &stu
tail = &stu // 需要把tail弄到新的节点重新初始化
}
}
/*
遍历链表
*/
func trans(p *Student) {
for p != nil {
fmt.Println(*p)
p = p.next
}
}

/*
头部插入法
*/
func insertHead(p **Student) {

for i := 0; i < 10; i++ {
stu := Student{
Name:  fmt.Sprintf("stu%d", i),
Age:   rand.Intn(100),
Score: rand.Float32() * 100,
}
stu.next = *p
*p = &stu
}
}

/*
删除节点 这里会有个问题,就是头节点不能删除
*/
func delNode(p *Student) {
var prev *Student = p // 这个是临时变量,保存上一个节点
for p != nil {
if p.Name == "stu6" {
prev.next = p.next // 上一个节点就等于下一个节点
break
}
prev = p // 这个是记录每次循环中的自己
p = p.next
}
}

/*
在指定节点插入一个节点
*/
func addNode(p *Student, newNode *Student) {

for p != nil {
if p.Name == "stu5" {
newNode.next = p.next //新节点的next等于当前节点的next
p.next = newNode      // 当前节点的next等于新节点的结构体
break
}
p = p.next
}
}

func main() {
var head *Student = new(Student) // 头节点
head.Age = 18
head.Score = 99
head.Name = "asdsad"
insertHead(&head) // 添加一些节点 循环去添加吧,模拟
delNode(&head) // 删除某一个链表

var newNode *Student = new(Student) // 插入一个节点
newNode.Age = 18
newNode.Score = 99
newNode.Name = "stu1000"
addNode(head, newNode) // 插入节点

trans(head) // 遍历
}
  • 点赞
  • 收藏
  • 分享
  • 文章举报
定西@hello_world 发布了17 篇原创文章 · 获赞 13 · 访问量 1096 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐