数组
一、数组是什么
Go 语言提供了数组类型的 数据结构。
-
数组是具有相同唯一类型的一组已编号且长度固定的数据项序列,这种类型可以是任意的原始类型。例如整型、字符串或者自定义类型。
-
数组元索可以通过索引(位置) 来读取(或者修改) ,索引从 0 开始,第一个元索索引为0,第二个索引为1,以此类推。数组的下标取值范国是从0开始,到长度减一。
数组一旦定义后,大小不能改变.
数组声明
Go 语言数组声明需要指定元素类型及元素个数,语法格式如下:
var 变量名 [大小] 变量类型
package main
import "fmt"
func main() {
// 定义一个数组 var 变量名 [大小]变量类型
var nums [4]int
// 数组的下标是从 0 开始的
nums[0] = 1
nums[1] = 2
nums[2] = 3
nums[3] = 4
fmt.Printf("%T\n", nums)
// 通过下标来获取数组元素
fmt.Println(nums[3])
fmt.Println(nums[2])
fmt.Println(nums[1])
fmt.Println(nums[0])
// 数组常用的方法
// 因为数组是固定长度的,所以长度和容量是相同的
length := len(nums)
capacity := cap(nums)
fmt.Println(length) // 输出长度
fmt.Println(capacity) // 输出容量
// 修改数组的值
fmt.Println(nums)
nums[0] = 6
fmt.Println(nums)
}
数组的定义:
- 数组是相同类型数据的有序集合
- 数组描述的是相同类型的若干个数据,按照一定的先后次序排序组合而成
- 其中,每一个数据称做一个数组元素,每个数组元素可以通过一个下标来访问它们
数组的基本特点:
- 其长度是确定的。数组一旦被创建,它的大小就是不可以改变的。
- 其元素必须是相同类型,不允许出现混合类型
二、初始化数组
初始化数组中 {} 的元素不能大于 [] 中的数字。
package main
import "fmt"
func main() {
// 常规的初始化
var arr1 = [4]int{
1, 2, 3, 4}
fmt.Println(arr1)
fmt.Println(arr1[0])
// 快速定义数组
arr2 := [4]int{
5, 6, 7, 8}
fmt.Println(arr2)
fmt.Println(arr2[0])
// 如果不确定数组长度
// 可以使用 ... 代替数组的长度
// 编译器会根据元素个数自行推断数组的长度
arr3 := [...]string{
"hello", "world", "!"}
fmt.Println(arr3)
fmt.Println(len(arr3))
fmt.Println(cap(arr3))
// 如果设置了数组的长度,我们可以通过指定下标来初始化元素
arr4 := [4]int{
1: 9, 3: 10}
fmt.Println(arr4)
}
输出
三、数组的遍历
package main
import "fmt"
/*
数组的遍历:
依次访问数组中的元素
方法1, arr[0],arr[1],arr[2]....
方法2:通过循环,配合下标
for i:=0;i<len(arr);i++{
arr[i]
}
方法3: range
range:词义“范围”
不需要操作数组的下标,到达数组的末尾,自动结束 for range循环
每次从数组中获取下标和对应位置的数值
*/
func main() {
// 常规的初始化
var arr1 = [4]int{
1, 2, 3, 4}
fmt.Println(arr1[0])
fmt.Println(arr1[1])
fmt.Println(arr1[2])
fmt.Println(arr1[3])
fmt.Println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
//采用for循环遍历输出
for i := 0; i < 4; i++ {
fmt.Println(arr1[i])
}
// 快捷键生成 arr1.for
// for range 可以得到 下标(index) 和 下标对应的值(value)
for index, value := range arr1 {
fmt.Println(index, value)
}
}
输出
四、数组类型
package main
import "fmt"
func main() {
num := 8
var arr1 = [4]int{
1, 2, 3, 4}
var arr2 = [4]string{
"hello", "wrold", "!"}
fmt.Printf("%T", arr1)
fmt.Println()
fmt.Printf("%T", arr2)
// 值类型:拷贝 arr
num2 := num
fmt.Println(num, num2)
num2 = 10
fmt.Println(num, num2)
fmt.Println(">>>>>>>>>>>>>>>>>>>>>>>>>>")
arr3 := arr1
fmt.Println(arr1)
fmt.Println(arr3)
fmt.Println(">>>>>>>>>>>>>>>>>>>>>>>>>>")
// 改变arr3并没有影响到arr1,数组也是值传递
arr3[0] = 66
fmt.Println(arr1)
fmt.Println(arr3)
}
输出
五、数组排序
- 数组的排序:让数组中的元素具有一定的顺序。
arr :=[5]int{
3,5,4,2,1}
升序:1,2,3,4,5
降序:5,4,3,2,1
栗子:
排序算法:冒泡排序、插入排序、选择排序、希尔排序、堆排序、快速排序……
- 冒泡排序
依次比较连个相邻的元素,如果他们的顺序(比如从小到大)就把他们交换过来。
package main
import "fmt"
func main() {
//3,5,4,2,1
//第一轮比较:3,4,2,1,5
//第二轮比较:3,2,1,4,5
//第三轮比较:2,1,3,4,5
//第四轮比较:1,2,3,4,5
//第五轮比较:1,2,3,4,5
arr := [5]int{
3, 5, 4, 2, 1}
//比较过后的数,在后面的比较还需要重新比较,这是多余的,增加了执行比较的次数
for j := 0; j < len(arr); j++ {
for i := 0; i < len(arr)-1; i++ {
if arr[i] > arr[i+1] {
arr[i], arr[i+1] = arr[i+1], arr[i]
}
}
fmt.Println(arr)
}
}
优化过后减少执行比较的次数
package main
import "fmt"
func main() {
//3,5,4,2,1
//第一轮比较:3,4,2,1,5
//第二轮比较:3,2,1,4,5
//第三轮比较:2,1,3,4,5
//第四轮比较:1,2,3,4,5
//第五轮比较:1,2,3,4,5
arr := [5]int{
3, 5, 4, 2, 1}
for j := 1; j < len(arr); j++ {
//两两比较,比较完成的数不用比较,即可减少执行比较的次数
for i := 0; i < len(arr)-j; i++ {
if arr[i] > arr[i+1] {
arr[i], arr[i+1] = arr[i+1], arr[i]
}
}
fmt.Println(arr)
}
}
package main
import "fmt"
func main() {
//3,5,4,2,1
//第一轮比较:3,4,2,1,5
//第二轮比较:3,2,1,4,5
//第三轮比较:2,1,3,4,5
//第四轮比较:1,2,3,4,5
//第五轮比较:1,2,3,4,5
arr := []int{
3, 5, 4, 2, 1, 6, 9, 8, 7, 0}
bubbleSort(arr)
}
// 函数的封装
func bubbleSort(arr []int) {
//需要比较的次数的一组数的个数-1
for j := 1; j < len(arr); j++ {
//两两比较,比较完成的数不用比较,即可减少执行比较的次数
for i := 0; i < len(arr)-j; i++ {
if arr[i] > arr[i+1] {
arr[i], arr[i+1] = arr[i+1], arr[i]
}
}
fmt.Println(arr)
}
}
升序输出
升序和降序输出
package main
import "fmt"
func main() {
//3,5,4,2,1
//第一轮比较:3,4,2,1,5
//第二轮比较:3,2,1,4,5
//第三轮比较:2,1,3,4,5
//第四轮比较:1,2,3,4,5
//第五轮比较:1,2,3,4,5
arr := []int{
3, 5, 4, 2, 1, 6, 9, 8, 7, 0}
bubbleSort(arr, "desc")
}
func bubbleSort(arr []int, c string) {
//需要比较的次数的一组数的个数-1
for j := 1; j < len(arr); j++ {
//两两比较,比较完成的数不用比较,即可减少执行比较的次数
for i := 0; i < len(arr)-j; i++ {
if c == "asc" {
if arr[i] > arr[i+1] {
arr[i], arr[i+1] = arr[i+1], arr[i]
}
}
if c == "desc" {
if arr[i] < arr[i+1] {
arr[i], arr[i+1] = arr[i+1], arr[i]
}
}
}
fmt.Println(arr)
}
}
降序输出
六、多维数组
Go 语言支持多维数组,以下为常用的多维数组声明方式:
var 变量名 [size1] [size2]...[size] 变量类型
二维数组是最简单的多维数组,二维数组本质上是由一维数组组成的,二维数组定义方式如下:
var 变量名 [x][y] 变量类型
二维数组可以认为是一个表格,x为行,y为列,下表格演示了一个二维数组 arr 为 三行四列:
arr | 列0 | 列1 | 列2 | 列3 |
---|---|---|---|---|
行0 | arr[0] [0] | arr[0] [1] | arr[0] [2] | arr[0] [3] |
行1 | arr[1] [0] | arr[1] [1] | arr[1] [2] | arr[1] [3] |
行2 | arr[2] [0] | arr[2] [1] | arr[2] [2] | arr[2] [3] |
通过数组下标输出数组元素
package main
import "fmt"
func main() {
arr := [3][4]int{
{
1, 2, 3, 4}, // row1
{
5, 6, 7, 8}, // row2
{
9, 10, 11, 12}, // row3
}
// 访问二维数组的行列
fmt.Println(arr[0][0])
fmt.Println(arr[0][1])
}
通过遍历输出数组元素
package main
import "fmt"
func main() {
arr := [3][4]int{
{
1, 2, 3, 4}, // row1
{
5, 6, 7, 8}, // row2
{
9, 10, 11, 12}, // row3
}
访问二维数组的行列
//fmt.Println(arr[0][0])
//fmt.Println(arr[0][1])
for i := 0; i < 3; i++ {
for j := 0; j < 4; j++ {
fmt.Println(arr[i][j])
}
}
for i, v := range arr {
fmt.Println(i, v)
for _, v2 := range v {
fmt.Println(v2)
}
}
}