简介

数组本质上是一种线性表数据结构,它用一组连续的内存空间,来存储一组具有相同类型的数据。

特性

可以使用下标直接访问数组元素
就数组增删改查的操作而言,数组拥有高效随机存取的特性,也存在低效插入、删除的劣势。

golang

在golang中,数组和切片是两个概念

数组

数组是一个由固定长度的特定类型元素组成的序列,一个数组可以由零个或多个元素组成。

可以使用len()函数获取数组的长度

切片

因为数组的长度是固定的,因此在Go语言中很少直接使用数组。和数组对应的类型是Slice(切片),它是可以增长和收缩的动态序列,slice功能也更灵活。

除了长度,切片多了容量属性,可以通过使用内置的 len()函数求长度,使用内置的cap()函数求容量。

相同

都可以直接通过下标的方式访问元素

区别

初始化

数组

a := [3]int{1,2,3} //指定长度
//or
a := [...]int{1,2,3} //不指定长度
//or
a := [...]int{99: -1}//指定初始化,只有最后一个元素初始化为-1,其余为0

数组可以拓展到多维数组

// 声明一个二维整型数组,两个维度的长度分别是 4 和 2
var array [4][2]int
// 使用数组字面量来声明并初始化一个二维整型数组
array = [4][2]int{{10, 11}, {20, 21}, {30, 31}, {40, 41}}
// 声明并初始化数组中索引为 1 和 3 的元素
array = [4][2]int{1: {20, 21}, 3: {40, 41}}
// 声明并初始化数组中指定的元素
array = [4][2]int{1: {0: 20}, 3: {1: 41}}

切片

s := make([]int) //创建一个长度为0,容量为0的切片
s := make([]int, 3, 5)//指定长度和容量
//or
s := []int{1,2,3} //不指定长度

切片同样可以拓展到多维切片

//声明一个二维切片
var slice [][]int
//为二维切片赋值
slice = [][]int{{10}, {100, 200}}

也可以使用循环完成初始化

    res:=make([][]int,n)
    for i:=range res{
        res[i]=make([]int,n)
    }

添加元素

虽然数组在初始化时也可以不指定长度,但 Go 语言会根据数组中元素个数自动设置数组长度,并且不可改变。

切片更像是一个动态的数组,可以通过 append 方法增加元素:

s := []int{1,2,3} //s = {1,2,3}
s = append(s, 4) //s = {1,2,3,4}
//添加多个元素
s = append(s, 1, 2, 3) // 追加多个元素, 手写解包方式
s = append(s, []int{1,2,3}...) // 追加一个切片, 切片需要解包

如果将 append 用在数组上,你将会收到报错:first argument to append must be slice。

复制

数组
在Go语言中,数组变量代表的是整个数组
所以在Go语言中,当数组变量B被赋值数组变量A时,实际上是数组变量B完全复制了一份数组A数据,而不是数组变量A和数组变量B指向同一份数据。

切片
Go语言的内置函数 copy() 可以将一个数组切片复制到另一个数组切片中,如果加入的两个数组切片不一样大,就会按照其中较小的那个数组切片的元素个数进行复制。

copy(slice2, slice1) // 复制slice1到slice2中

其中slice2, slice1指向同一个数组
详见https://segmentfault.com/a/11...

函数传递

当切片和数组作为参数在函数(func)中传递时,数组传递的是值,而切片传递的是指针。因此当传入的切片在函数中被改变时,函数外的切片也会同时改变。相同的情况,函数外的数组则不会发生任何变化。

常见操作

排序

一般使用sort包完成排序操作

sort 包 在内部实现了四种基本的排序算法:插入排序(insertionSort)、归并排序(symMerge)、堆排序(heapSort)和快速排序(quickSort); sort 包会依据实际数据自动选择最优的排序算法。

对 int、string、float64 的切片
可以直接使用函数

func Ints(a []int)                       //Ints 以升序排列 int 切片。
func Strings(a []string)//Strings 以升序排列 string 切片。
func Float64s(a []float64)     //Float64s将类型为float64的slice a以升序方式进行排序

可以使用AreSorted()方法(例如Float64sAreSorted(),IntsAreSorted()等)来检查值是否排序,结果将会返回一个布尔值。

另外也可以用reserve函数完成降序排序

    intList := [] int {2, 4, 3, 5, 7, 6, 9, 8, 1, 0}
    float8List := [] float64 {4.2, 5.9, 12.3, 10.0, 50.4, 99.9, 31.4, 27.81828, 3.14}
    stringList := [] string {"a", "c", "b", "d", "f", "i", "z", "x", "w", "y"}

    sort.Sort(sort.Reverse(sort.IntSlice(intList)))
    sort.Sort(sort.Reverse(sort.Float64Slice(float8List)))
    sort.Sort(sort.Reverse(sort.StringSlice(stringList)))

另外,sort还提供了对于切片的一般方法
实现 sort.Interface 接口,提供 Len、Less、Swap 三个方法的实现,然后调用 sort.Sort() 。Interface 的具体定义如下:
type Interface interface {

// Len is the number of elements in the collection.
Len() int
// Less reports whether the element with
// index i should sort before the element with index j.
Less(i, j int) bool
// Swap swaps the elements with indexes i and j.
Swap(i, j int)

}

搜索某个元素并返回下标

func Search(n int, f func(int) bool) int

search使用二分法进行查找,Search()方法回使用“二分查找”算法来搜索某指定切片[0:n],并返回能够使f(i)=true的最小的i(0<=i<n)值,并且会假定,如果f(i)=true,则f(i+1)=true,即对于切片[0:n],i之前的切片元素会使f()函数返回false,i及i之后的元素会使f()函数返回true。但是,当在切片中无法找到时f(i)=true的i时(此时切片元素都不能使f()函数返回true),Search()方法会返回n(而不是返回-1)。

Search 常用于在一个已排序的,可索引的数据结构中寻找索引为 i 的值 x,例如数组或切片。这种情况下,实参 f,一般是一个闭包,会捕获所要搜索的值,以及索引并排序该数据结构的方式。


wric
10 声望3 粉丝