首先,我们知道链表的特性,分别有单线链表和双线链表,下面我用golang来模拟了一个单线链表
链表的添加,他其实分别是有头部插入法和尾部插入法的,我在代码中都写了这两个方法
结构体 Student 是必须要有一个指针,这个指针是指向下一个链表的,当然,如果是双向链表的话,这里还需要记录一个头部指针,也就是说这个结构体会有两个指针
type Student struct {
Name string
Age int
Score float32
next *Student
}
一个小细节:在插入某一个节点,比如 a b c 三个节点,我需要插入一个d 在 a 和 b 之间,这时候遍历到b 之后再进行插入,不然你如果在a的时候就开始进行插入操作,那么你是获取不到b节点的尾部的
双向链表
完整的代码:
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) // 遍历
}