Go 学习之结构体链表 (一)

一、结构体

  1. 用来自定义复杂数据结构
  2. struct里面可以包含多个字段(属性)
  3. struct类型可以定义方法,注意和函数的区分
  4. struct类型是值类型
  5. struct类型可以嵌套
  6. 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
}

如果有两个指针分别指向前一个节点和后一个节点,我们叫做双链表。

file

代码

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>}

为者常成,行者常至