Go中的切片
在golang中,切片的底层就是数组,切片是对底层数组的引用,当传递一个切片给函数时,实际上是传递了切片的引用。因此,在函数内部修改切片的内容会影响原始切片。
切片中增加元素
思路分析
- 先声明并初始化一个长度为当前切片长度+1的切片
- 首部添加:将其余全部向后移动一位,然后给首位赋值即可。
- 尾部添加:直接给尾部赋值即可。
- 中间添加:先查找到要添加的位置,然后将添加位置后的元素全部向后移动一位,然后给添加的位置赋值即可。
* 这里假定该切片是单调序列,为了提高查询效率,使用二分法查找。
Go代码
// 在数组首部插入元素
func AddFirstInArr(arr []int, val int) []int{
newArr := make([]int, len(arr)+1)
newArr[0] = val
// 下面for循环也可以换成内置copy函数:
// copy(newArr[1:], arr)
for i:=1;i<len(newArr);i++ {
newArr[i] = arr[i-1]
}
return newArr
}
// 在数组尾部插入元素
func AddLastInArr(arr []int, val int) []int{
newArr := make([]int, len(arr)+1)
// 下面for循环也可以换成内置copy函数:
// copy(newArr, arr)
for i:=0;i<len(arr);i++ {
newArr[i] = arr[i]
}
newArr[len(newArr)-1] = val
return newArr
}
// 在数组中间插入元素
func AddInArr(arr []int, val int) []int{
arrlen := len(arr)
left,right := 0, arrlen-1
// 假设应该插到最后
findindex := arrlen
// 使用二分查找法找到val对应的位置
// 升序
if arr[left] <= arr[right] {
for left <= right {
mid := (right-left)/2+left
if val <= arr[mid] {
right = mid-1
findindex = mid
} else {
left = mid+1
}
}
} else {
for left <= right {
mid := (right-left)/2+left
if val >= arr[mid] {
right = mid-1
findindex = mid
} else {
left = mid+1
}
}
}
newArr := make([]int, arrlen+1)
// 下面for循环也可以换成内置copy函数:
// copy(newArr[:findindex], arr)
// copy(newArr[findindex+1:], arr[findindex:])
for i:=0;i<arrlen;i++ {
if i < findindex {
newArr[i] = arr[i]
} else {
newArr[i+1] = arr[i]
}
}
newArr[findindex] = val
return newArr
}
切片中删除元素
思路分析
- 先判断当前切片长度是否为空,如果是空,则直接返回了,没有元素可以删除的。
- 然后要除切片,可以通过重新切片的方式实现。
- 首部删除:直接使用切片做法 arr[1:]即可。(复杂化:将该切片除了首位其余全部想前移动一位,然后 arr[:len(arr)-1])
- 尾部删除:直接使用arr[:len(arr)-1]
- 中间删除:先查找要删除元素的位置索引,没有找到则直接返回;找到了就将删除位置后的所有元素都向前移动一位,然后 arr[:len(arr)-1]
Go代码
// 删除数组首位
func DelFirstInArr(arr []int) []int{
if len(arr) == 0 {
return arr
}
return arr[1:]
}
// 删除数组末尾元素
func DelLastInArr(arr []int) []int{
if len(arr) == 0 {
return arr
}
return arr[:len(arr)-1]
}
// 删除数组中间元素
func DelInArr(arr []int, val int) []int{
arrlen := len(arr)
if arrlen == 0 {
return arr
}
findindex := -1
for i, k := range arr {
if k == val {
findindex = i
break
}
}
if findindex == -1 {
fmt.Println("数组中不存在要删除的元素 ", val)
return arr
}
// 将要删除元素后的所有元素都往前移动一位
copy(arr[findindex:], arr[findindex+1:])
return arr[:arrlen-1]
}