基础篇——数组与链表



理论介绍

数组&切片

在go语言的复合数据类型中,需要认识两种必要的数据类型

  • 数组
  • 切片

数组跟切片都是指一系列同一类型数据的结合。数组中包含的每个数据被称为数组元素,一个数组包含的元素个数成为数组的长度。不过,在go语言中数组与切片有一个很大的区别,数组长度在定义后不可更改,数组声明的时候指定的元素个数,就是此数组添加元素的上限数目。

切片可以动态扩充存放空间,可以被随意传递不会导致管理的元素被复制。相比数组,切片是开发中更多的被用到的数据类型。

不管是数组还是切片,在go语言中使用都非常简单,下面通过实际的代码案例来看看,数组跟切片的使用

数组的性质:
- 访问元素容易
- 更新困难

代码实战

# array.go

package common

import (
    "fmt"
)

func Arr()  {
    a := [2] int{1, 2}   // 数组, 一开始就分配好了内存,大小限定,不能拓展
    b := []int{1, 2, 3, 4, 5, 6, 7}  // 切片,大小没有限定,可以动态拓展

    for _, i := range a{
        fmt.Printf("a 数组遍历 %d\n", i)
    }

    for _, j := range b{
        fmt.Printf("b 切片遍历 %d\n", j)
    }

    // 输出数组的第二个元素
    fmt.Printf("a的第二个元素 %d\n", a[1])

    // 输出切片的第五个元素
    fmt.Printf("b的第五个元素 %d\n", b[4])
}

在上述代码中,我们分别声明了数组跟切片,并分别进行了遍历与访问,操作都有注释,可以直接看代码注释理解。

代码测试

# main.go
package main

import "github.com/csunny/argo/src/common"

func main()  {
    common.Arr()
}

在go语言中程序包的入口是main包, 函数的入口是main函数,所以代码中我们在main包里面有个main函数,通过main函数执行我们的代码。 在go中引入一个包用的是import,后面跟的是包的路径。 
注意 go语言中的私有、公有变量是直接根据命名规则来区分的,小写为私有、大写为公有。所以我们在这里Arr首字母用的是大写,这样我们Arr就是一个公有变量,可以在其他包里面直接引用。

链表

相比数组,链表是要稍微复杂一点的数据结构。链表是一种线性表,但是不会按照线性的顺序存储数据,而是在每一个节点里面存到写一个节点的指针。链表的特性:
- 插入元素容易
- 元素访问困难

代码实战

package linklist

import (
    "fmt"
    "log"
)

// Item 可以理解为范性,也就是任意的数据类型
type Item interface {

}

// 一个节点,除了自身的数据之外,还必须指向下一个节点,尾部节点指向为nil
type LinkNode struct {
    Payload Item    //  Payload 为任意数据类型
    Next *LinkNode
}

// go语言方法,对比与下面的NewLinkNode,方法可以理解为面向对象里面对象的方法,虽然实现的功能
// 跟函数类似,但是方式是绑定在对象上的,也就是说我们此处的Add是绑定与head这个LinkNode对象的。
// 这个是go语言区别与其他语言的设计方式,也是go语言很重要的一部分。
func (head *LinkNode) Add(payload Item)  {
    // 这里采用尾部插入的方式,给链表添加元素
    point := head

    for point.Next != nil{
        point = point.Next
    }
    newNode := LinkNode{payload, nil}
    point.Next = &newNode


    // 头部插入
    //newNode := LinkNode{payload, nil}
    //newNode.Next = head
}

// 创建一个新的链表。 函数,对比与上面的方法,函数是没有绑定任何对象的。
// go语言的函数需要指明参数跟返回值,在此函数中,我们的参数是length,返回值是一个LinkNode对象
// 除了绑定之外,函数跟方法并没有什么不同
func NewLinkNode(length int) *LinkNode  {
    if length <= 0{
        fmt.Printf("链表长度必须大于0")
        log.Panic("链表长度必须大于0")
    }
    var head *LinkNode

    head = &LinkNode{}

    for i := 0; i<length; i++{
        var newNode *LinkNode
        newNode = &LinkNode{Payload: i}
        newNode.Next = head
        head = newNode
    }
    return head
}

在代码中,我们首先创建了一个LinkNode对象,一个LinkNode对象包含两个元素,一个是Payload(参数)另一个是Next也就是下一个节点。 我们用go语言的语法,实现了一个Add方法,此方法可以用于添加元素。在一个链表中添加元素可以采用头部插入,或者尾部插入。当然中间插入也是可行的,只需要将之前的链接断开,然后重新链接就可以了。

NewLinkNode,用于创建一个指定长度的链表,接收一个int类型的参数,返回链接的头节点。详细的内容可以看注释。以下为测试代码:

package linklist

import "testing"

func TestLinkNode_Add(t *testing.T) {
    head := NewLinkNode(10)

    for head.Next != nil{
        t.Errorf("%s", head.Payload)
        head = head.Next
    }

}

测试代码我们对链表进行了遍历,输出我们放在了error里面,大家可以运行go test查看输出。以上就是简单的关于go语言对数组跟链表的介绍。

项目地址

参考教程

猜你喜欢

转载自blog.csdn.net/afar_ch/article/details/81153153
今日推荐