/*冒泡排序:
* 时间复杂度O(n^2)
* 空间复杂度O(1)
* 稳定
*/
func bubbleSort(arr []int) []int {
if len(arr) <= 0 {
return arr
}
for i := 0; i < len(arr)-1; i++ {
for j := 0; j < len(arr)-1-i; j++ {
if arr[j] > arr[j+1] {
tmp := arr[j]
arr[j] = arr[j+1]
arr[j+1] = tmp
}
}
}
return arr
}
/*选择排序:
* 时间复杂度O(n^2)
* 空间复杂度O(1)
* 不稳定
*/
func selectSort(arr []int) []int {
if len(arr) <= 0 {
return arr
}
for i := 0; i < len(arr)-1; i++ {
minIndex := i
for j := i + 1; j < len(arr); j++ {
if arr[j] < arr[minIndex] {
minIndex = j
}
}
tmp := arr[i]
arr[i] = arr[minIndex]
arr[minIndex] = tmp
}
return arr
}
/*直接插入排序:
* 时间复杂度O(n^2)
* 空间复杂度O(1)
* 稳定
*/
func insertSort(arr []int) []int {
for i := 1; i < len(arr); i++ {
tmp := arr[i]
j := i
for ; j > 0; j-- {
if tmp < arr[j-1] {
arr[j] = arr[j-1]
} else {
break
}
}
arr[j] = tmp
}
return arr
}
/*希尔排序:
* 时间复杂度O(n^1.3)
* 空间复杂度O(1)
* 不稳定
*/
func shellSort(arr []int) []int {
for k := len(arr) / 2; k > 0; k = k / 2 {
for i := k; i < len(arr); i++ {
tmp := arr[i]
j := i
for ; j >= k; j -= k {
if tmp < arr[j-k] {
arr[j] = arr[j-k]
} else {
break
}
}
arr[j] = tmp
}
}
return arr
}
/*归并排序:
* 时间复杂度O(NlogN)
* 空间复杂度O(n)
* 稳定
*/
func mergeSort(arr []int) []int {
length := len(arr)
if length < 2 {
return arr
}
mid := length / 2
return merge(mergeSort(arr[0:mid]), mergeSort(arr[mid:]))
}
func merge(left, right []int) []int {
lCount := len(left)
rCount := len(right)
arr := make([]int, 0)
i := 0
j := 0
for i < lCount && j < rCount {
if left[i] <= right[j] {
arr = append(arr, left[i])
i++
} else {
arr = append(arr, right[j])
j++
}
}
arr = append(arr, left[i:]...)
arr = append(arr, right[j:]...)
return arr
}
/*快速排序: 冒泡的升级版(减少了总交换次数)
* 时间复杂度O(NlogN)
* 空间复杂度O(logN)
* 不稳定
*/
func quickSort(arr []int) {
qSort(arr, 0, len(arr)-1)
}
func qSort(arr []int, low, high int) {
if low < high {
p := partitionVal(arr, low, high)
qSort(arr, low, p-1)
qSort(arr, p+1, high)
}
}
func partitionVal(arr []int, low, high int) int {
tmp := arr[low]
for low < high {
for low < high && arr[high] >= tmp {
high--
}
val := arr[low]
arr[low] = arr[high]
arr[high] = val
for low < high && arr[low] < tmp {
low++
}
val = arr[low]
arr[low] = arr[high]
arr[high] = val
}
return low
}
/*堆排序:选择排序的升级版(把每次比较的结果存下来再做相应调整)
* 不适合待排序序列个数较少的情况
* 时间复杂度O(NlogN)
* 空间复杂度O(1)
* 不稳定
*/
func heapSort(arr []int) {
//二叉树的最后一个有孩子的节点的下标是n/2-1,
//从右往左,从下往上将根节点及其子树调整大根堆
for i := len(arr)/2 - 1; i >= 0; i-- {
heapAdjust(arr, i, len(arr))
}
//遍历每次都将根节点和未交换过的末尾节点交换,再构造大根堆,重复直到所有元素都有序
length := len(arr)
for i := length - 1; i >= 0; i-- {
tmp := arr[0]
arr[0] = arr[i]
arr[i] = tmp
heapAdjust(arr, 0, i)
}
}
func heapAdjust(arr []int, low, high int) {
i := low
tmp := arr[low]
for j := 2*i + 1; j < high; j = j*2 + 1 {
if j < high-1 && arr[j] < arr[j+1] { //可能没有右孩子
j++
}
if arr[j] <= tmp { //如果根已经是最大的就不需要调整了,循环结束
break
}
arr[i] = arr[j]
i = j
}
arr[i] = tmp
}
/*计数排序: 适合当maxValue不是很大并且序列比较集中时
* 时间复杂度O(n)
* 空间复杂度O(n)
* 稳定
*/
func countSort(arr []int, maxValue int) {
bucket := make([]int, maxValue+1)
for i := 0; i < len(arr); i++ {
bucket[arr[i]]++
}
idx := 0
for j := 0; j < len(bucket); j++ {
for bucket[j] > 0 {
arr[idx] = j
idx++
bucket[j]--
}
}
}
/* 桶排序:计数排序升级版
* 数据均匀分布在各个桶中排序最快,数据被分在同一个桶中排序最慢
* 时间复杂度O(n)
* 空间复杂度O(n)
* 稳定
*/
func bucketSort(arr []int, bucketCount int) {
maxVal := math.MinInt64
for i := 0; i < len(arr); i++ {
if arr[i] > maxVal {
maxVal = arr[i]
}
}
buckets := make([][]int, bucketCount)
space := maxVal / (bucketCount - 1)
for i := 0; i < len(arr); i++ {
idx := arr[i] / space
buckets[idx] = append(buckets[idx], arr[i])
}
pos := 0
for i := 0; i < bucketCount; i++ {
bucketLen := len(buckets[i])
if bucketLen <= 0 {
continue
}
insertSort(buckets[i])
for k := 0; k < bucketLen; k++ {
arr[pos] = buckets[i][k]
pos++
}
}
}
排序算法
最新推荐文章于 2023-02-12 20:42:34 发布