随着Go+ 的发布不久,正准备学习GO+,又刚好赶上这次征文的活动
以写促学,今后,我将带大家使用 GO+ 逐步 实现常见的数据结构 ,刚好一边学习GO+一边复习数据结构
今天是第一篇
我们使用 GO+ 来学习数据结构 之 数组、切片与Map
数组基本操作
声明
一维数组
初始化数组长度为1
var linearArray [1]int
根据数组内容自己推算长度
linearArray := [...]int{1,2,3}
对于var和:=的区别在于:var适合全局:=只能试用局部
Golang 中数组的初始值如果不声明,则默认是全部有初值的
比如 linearArray 这个数组声明了长度为 1, Go 的编译器会把这 1 个元素全都初始化为 0
bool 值类型的数组,如果不做赋值操作,则初始值全为 false
我们可以来试验一下
package main func main() { var linearArray [1]int print linearArray[0] }
package main func main() { var linearArray [1]bool print linearArray[0] }
二维数组
二维数组声明和其它语言差不多
var twoDimensionalArray [1][2]int
遍历
linearArray := [...]int{1,2,3} for x <- linearArray, x > 1 { print x }
另一种遍历方法:
linearArray := [...]int{5, 4, 3, 2, 1, 0} for index, value := range linearArray { println "索引:",index,", 值: ",value }
当然你也可以使用最基础的方式遍历
linearArray := [...]int{5, 4, 3, 2, 1, 0} for i := 0; i < len(linearArray); i++ { println linearArray[i] }
切片基本操作
数组是按值传递的(即是传递的副本),而切片是引用类型,传递切片的成本非常小,而且不定长,如果很难理解的话,可以暂时把它理解为"可以自定义长度的列表"或者是“可扩容的数组”
语法如下:
- make([ ]Type, length, capacity)
其长度为切片的容量 capacity
- make([ ]Type, length)
其长度记为切片的长度 length
- [ ]Type{}
- [ ]Type{value1, …, valueN}
使用make()函数创建切片、映射和通道,通过内置的函数 append() 来增加切片的容量。
slice := []int{} for i := 0; i < 5; i++ { slice = append(slice, i) } print slice
此外,和python类似,我们可以这样提取区间数据
slice := []int{} for i := 0; i < 5; i++ { slice = append(slice, i) } print slice[1:3]
提取slice中第一个开始到第三个数值(不包括第三个)
[n:m] 的意思就是取
区间 [n,m)
从位置下标的角度上来说 [n-1,m-1) 可能更合适, 为什么呢?
我们可以来实现下这个功能
func ExtractInterval(sliceObject []int, start int, end int) []int { new_sliceObject := []int{} for i := start - 1; i < end-1; i++ { new_sliceObject = append(new_sliceObject, sliceObject[i]) } return new_sliceObject } slice := []int{} for i := 0; i < 5; i++ { slice = append(slice, i) } print ExtractInterval(slice, 1, 3)
你可以发现:在我们ExtractInterval方法中所实现的就是提取slice数组中的下标位置是0和1的数据
更多知识点
Go+ 切片的扩容规则
切片的扩容并不会改变原来的切片,它会生成一个容量更大的切片,然后将把原有的元素和新元素一并拷贝到新切片中. 一般的情况下,你可以简单地认为新切片的容量将会是原切片容量的 2 倍.
当原切片的长度大于或等于 1024 时,Go+会以原容量的 1.25 倍作为新容量的基准. 如果容量增加的太快,很容易浪费空间.
如果我们一次追加的元素过多,要大于 2 倍,那么新容量就会以新长度为基准. 比如你现在的切片长度为 5,现在一下往里面添加了 25 个元素,那么 Go+ 会直接创建一个长度为 30 的底层数组,然后把所有的数据拷贝进去.
Go+ 切片其底层数组永远不会改变
当切片需要扩容时,新的切片诞生的同时也会创建出新的底层数组,它只是把原数组的数据拷贝了进来,并未对其做任何的修改.
Map literal(集合)
声明
定义,个人感觉和Python是差不多的
MapLiteral := {"a": 1, "b": 2, "c": 3, "d": 4, "e": 5}
遍历
MapLiteral := {"a": 1, "b": 2, "c": 3, "d": 4, "e": 5} for k, v := range MapLiteral { println "k:[", k, "].v:[", v, "]\n" }
删除
delete() 方法可以实现
delete(集合, key)
还可以试一下这样定义集合,顺便试验下delete() 方法
MapLiteral := map[string]int{"a": 1, "b": 2, "c": 3, "d": 4, "e": 5} delete(MapLiteral, "a") for k, v := range MapLiteral { println "k:[", k, "].v:[", v, "]\n" }
修改与增加
可以直接这样实现
MapLiteral := map[string]int{"a": 1, "b": 2, "c": 3, "d": 4, "e": 5} MapLiteral["a"] = 0 MapLiteral["f"] = 6 for k, v := range MapLiteral { println "k:[", k, "].v:[", v, "]\n" }
练习
请使用GO+ 实现简单的 冒泡排序
Array := [...]int{123, 343, 143, 524, 462, 5672, 3467} // 冒泡排序 for i := 0; i < len(Array); i++ { for j := 1; j < len(Array)-i; j++ { if Array[j] < Array[j-1] { Array[j], Array[j-1] = Array[j-1], Array[j] } } } print Array