Go 学习之结构体链表 (一)
一、结构体
- 用来自定义复杂数据结构
- struct里面可以包含多个字段(属性)
- struct类型可以定义方法,注意和函数的区分
- struct类型是值类型
- struct类型可以嵌套
- Go语言没有class类型,只有struct类型
声明
type 标识符 struct {
field1 type
field2 type
}
例子:
type Student struct {
Name string
Age int
Score int
}
struct定义的三种形式:
- a、var stu Student
- b、var stu *Student = new (Student)
- c、var stu *Student = &Student{}
其中b和c返回的都是指向结构体的指针,访问形式如下:
a. stu.Name、stu.Age和stu.Score或者 (*stu).Name、(*stu).Age等
代码:
package main
import "fmt"
type Student struct {
Name string
Age int
Score float32
}
func main() {
var stu Student
stu.Age = 26
stu.Name = "Lily"
stu.Score = 90
// 第二种方法
var stu2 = Student{
Age: 20,
Name: "Corwien",
Score: 15,
}
fmt.Println(stu.Age)
fmt.Printf("Age:%p\n", &stu.Age)
fmt.Printf("Name:%p\n", &stu.Name)
fmt.Printf("Score:%p\n", &stu.Score)
}
二、链表
1、链表定义
type Student struct {
Name string
Next* Student
}
每个节点包含下一个节点的地址,这样把所有的节点串起来了,通常把链表中的第一个节点叫做链表头。
单链表只能从头到尾。
2、双链表定义
type Student struct {
Name string
Next* Student
Prev* Student
}
如果有两个指针分别指向前一个节点和后一个节点,我们叫做双链表。

代码
package main
import "fmt"
type Student struct {
Name string
Age int
Score float32
next *Student
}
func main() {
var head Student
head.Name = "Xiu"
head.Age = 18
head.Score = 99
var stu1 Student
stu1.Name = "stu1"
stu1.Age = 20
stu1.Score = 80
// stu1.next = nil
head.next = &stu1
// 遍历
var p *Student = &head
for p != nil {
fmt.Println(*p)
p = p.next
}
}
结果打印:
{Xiu 18 99 0xc420078000}
{stu1 20 80 <nil>}
再加入一个节点:
package main
import "fmt"
type Student struct {
Name string
Age int
Score float32
next *Student
}
func trans(p *Student) {
for p != nil {
fmt.Println(*p)
p = p.next
}
}
func main() {
var head Student
head.Name = "Xiu"
head.Age = 18
head.Score = 99
var stu1 Student
stu1.Name = "stu1"
stu1.Age = 20
stu1.Score = 80
// stu1.next = nil
head.next = &stu1
// trans(&head)
// 再插入一个节点
var stu2 Student
stu2.Name = "stu2"
stu2.Age = 25
stu2.Score = 85
stu1.next = &stu2
trans(&head)
}
打印:
{Xiu 18 99 0xc4200720c0}
{stu1 20 80 0xc4200720f0}
{stu2 25 85 <nil>}
循环尾部插入:
package main
import (
"fmt"
"math/rand"
)
type Student struct {
Name string
Age int
Score float32
next *Student
}
func trans(p *Student) {
for p != nil {
fmt.Println(*p)
p = p.next
}
}
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
}
}
func main() {
var head Student
head.Name = "Xiu"
head.Age = 18
head.Score = 99
// 循环插入尾部节点
insertTail(&head)
trans(&head)
}
打印:
{Xiu 18 99 0xc4200140c0}
{stu0 81 94.05091 0xc4200140f0}
{stu1 47 43.77142 0xc420014120}
{stu2 81 68.682304 0xc420014150}
{stu3 25 15.651925 0xc420014180}
{stu4 56 30.091187 0xc4200141b0}
{stu5 94 81.36399 0xc4200141e0}
{stu6 62 38.06572 0xc420014210}
{stu7 28 46.888985 0xc420014240}
{stu8 11 29.310184 0xc420014270}
{stu9 37 21.855305 <nil>}
头部插入:
package main
import (
"fmt"
"math/rand"
)
type Student struct {
Name string
Age int
Score float32
next *Student
}
func trans(p *Student) {
for p != nil {
fmt.Println(*p)
p = p.next
}
}
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
}
}
func main() {
// &Student{}
var head *Student = new(Student)
head.Name = "Xiu"
head.Age = 18
head.Score = 99
// 循环插入尾部节点
// insertTail(&head)
// 头部插入
for i := 0; i < 10; i++ {
stu := Student{
Name:fmt.Sprintf("stu%d", i),
Age: rand.Intn(100),
Score: rand.Float32() * 100,
}
stu.next = head
head = &stu
}
trans(head)
}
打印:
{stu9 37 21.855305 0xc420014330}
{stu8 11 29.310184 0xc420014300}
{stu7 28 46.888985 0xc4200142d0}
{stu6 62 38.06572 0xc4200142a0}
{stu5 94 81.36399 0xc420014270}
{stu4 56 30.091187 0xc420014240}
{stu3 25 15.651925 0xc420014210}
{stu2 81 68.682304 0xc4200141e0}
{stu1 47 43.77142 0xc4200141b0}
{stu0 81 94.05091 0xc420014180}
{Xiu 18 99 <nil>}
为者常成,行者常至
自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)