##
需求
排序操作,列举常见的几种排序模型:冒泡、选择、插入、快排
备注:需求和运行输出结果均已在代码中注释
冒泡
代码:
1 | package main |
选择
代码:
1 | package main |
插入
代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38package main
import "fmt"
/*
思路:
假设arr有n个元素,无序的,
新建一个newArr数组,这个数组要求有序(假设从小至大),默认只放入arr[0]这一个元素,arr后面的元素,依次比较,按照合理的位置插入newArr数组中
最后组合成新的完整有序的newArr
*/
func main() {
arr := [7]int{9, 11, 4, 7, 15, 12, 6}
newArr := [7]int{}
newArr[0] = arr[0]
/*
newArr首位元素与arr首元素相等无需比较,因此arr从第1位开始取出元素与newArr中所有的进行比较,即arr[i]中的元素,与newArr[0..i-1]
进行倒序逐个比较,arr[i]大则插入比较元素newArr[j]的右边,arr[i]小则继续向左移动。在选择插入合适位置时,如果插入之后再来移动其右
边的元素,复杂度高,因此:
1.若比较元素newArr[j] > arr[i]大,则提前将j的下一位newArr[j+1]赋值成newArr[j],相当于变相地将newArr[j]往后移动一位,给前方提前预留一个位置出来,合适的时候给arr[i]插入
2.若newArr[j] < arr[i],则说明arr[i]已经找到了合适的位置,即j的下一位newArr[j+1],将newArr[j+1]赋值为arr[i],本次循环完成,进入下一次循环
*/
for i := 1; i < len(arr); i++ {
for j := i - 1; j >= 0; j-- {
if arr[i] < newArr[j] {
newArr[j+1] = newArr[j]
// 如果是arr[i]比newArr[0]还小,则arr[i]成为新的newArr[0]
if j == 0 {
newArr[0] = arr[i]
}
} else {
newArr[j+1] = arr[i]
break
}
}
}
fmt.Println(newArr)
}
快排1
1 | package main |
快排2
1 | package main |
总结
时间复杂度对比:
冒泡:O(n^2)
选择:O(n^2)
插入:O(n^2)
快排:O(nlogn)
冒泡和选择排序复杂度基本一致,插入排序在最差情况下复杂度与前两者一致,但平均复杂度低于前两者,快排要快上不少,基于快排1稍稍改动了一下思路,实现的快排2,思路方面个人认为快排2更便于理解,同时更贴近递归的深度优先理念,深入到最内层先找到最小的元素。