排序算法实现(go语言)


冒泡排序

算法原理:按照从左至右(或从右至左)顺序依次对相邻两元素进行比较和排序,较大数据往下沉,较小数据向上冒泡.
时间复杂度: O( n 2 n^2 n2)

  • 普通方法实现

    /**
      go默认值传递,所以此处需要使用指针修改原数组
    */
    func bubbleSort(arr *[6]int) [6]int{
    n := len(*arr)
    for i:=0;i<n;i++ { // 每一轮确定一个最大值
    	for j:=1;j<n-i;j++ { // 每一轮过后有i个元素被排好序
    		if (*arr)[j-1] > (*arr)[j] {
    			tmp := (*arr)[j-1]
    			(*arr)[j-1] = (*arr)[j]
    			(*arr)[j] = tmp
    		}
    	}
    }
    return *arr
    }
    
  • 改进算法1

/**
*    添加一个exchange标志,如果未发生交换这说明数据已经排好序无需后续比较
*/
func bubbleSort2(arr *[6]int) [6]int {
	n := len(arr)
	for i := 0; i < n; i++ {
		exchange := false
		for j := 1; j < n-i; j++ {
			if (*arr)[j-1] > (*arr)[j] { // 每一轮过后有i个元素被排好序
				tmp := (*arr)[j-1]
				(*arr)[j-1] = (*arr)[j]
				(*arr)[j] = tmp
				exchange = true
			}
		}
		if !exchange {
			break
		}
		fmt.Printf("第%d轮排序结果:%v\n", (i+1), *arr)
	}
	return *arr
}
  • 改进算法2
/**
* 设置pos指针,pos后面的数据不用再参与排序
*/
func bubbleSort3(arr *[6]int) [6]int{
	 counter := 1
	 endPoint := len(arr) - 1

	 for endPoint > 0 {
		pos := 1
		for j:=1;j<=endPoint;j++ {
			if (*arr)[j-1] > (*arr)[j] { // 每一轮过后有i个元素被排好序
				tmp := (*arr)[j-1]
				(*arr)[j-1] = (*arr)[j]
				(*arr)[j] = tmp
				
				pos = j; // 第j个元素发生交换
			}
		}
		endPoint = pos - 1
		fmt.Printf("第%d轮排序结果:%v\n", counter, *arr)
		counter++
	 }
	 return *arr
}
选择排序

算法原理:第一次循环选出最大值与数组第一个元素交换,第二次循环选出第二大元素与数组第二个元素交换…依次类推。
时间复杂度: O( n 2 n^2 n2);

func selectSort(arr *[6]int) [6]int {
	n := len(arr)

	for i := 0; i < n-1; i++ {
		minPoint := i
		for j := i + 1; j < n; j++ {
			if (*arr)[j] < (*arr)[minPoint] {
				minPoint = j
			}
		}

		if minPoint != i {
			tmp := (*arr)[i]
			(*arr)[i] = (*arr)[minPoint]
			(*arr)[minPoint] = tmp
		}
		fmt.Printf("第%d轮排序结果:%v\n", (i+1), *arr)
	}
	return *arr
}
插入排序

算法原理:假设前面(n-1)[n>=2] 个数已经是排好顺序的,现在要把第n个数找到相应位置并插入。
时间复杂度: O( n 2 n^2 n2);

  • 代码实现
func insertSort(arr *[6]int) [6]int {
	n := len(arr)
	for i:=1;i<n-1;i++ {
		tmp := arr[i]
		insertPoint := i - 1
		for insertPoint >= 0 && (*arr)[insertPoint] > tmp {
			(*arr)[insertPoint + 1] = (*arr)[insertPoint]
			insertPoint--
		}
		(*arr)[insertPoint + 1] = tmp // 确认好插入位置后替换对应的值
		fmt.Printf("第%d轮排序结果:%v\n", i, *arr)
	}
	return *arr
}
归并排序

算法原理: 采用分而治之的思想,不停对数组进行拆分,最后再合并两个数组,最终返回合并后的结果
时间复杂度: O( n ∗ log ⁡ 2 3 n*\log_{2}{3} nlog23)

func mergeSort(arr *[6]int, low int, high int) {
	if low == high {
		return
	} else {
		mid := (low + high) / 2
		mergeSort(arr, low, mid)
		mergeSort(arr, mid+1, high)
		merge(arr, low, mid, high)
	}
}

func merge(a *[6]int, low int, mid int, high int) {
	count := high - low + 1
	workSpace := make([]int, count)
	// 注意:low的值后面会使用,所以采用更新临时变量方式
	l, h, m, n := low, high, mid, mid+1
	j := 0
	for l <= mid && n <= h {
		if (*a)[l] <= (*a)[n] {
			// 注意数组不能j++,测试使用报错
			workSpace[j] = (*a)[l]
			j++
			l++
		} else {
			workSpace[j] = (*a)[n]
			j++
			n++
		}
	}

	for l <= m {
		workSpace[j] = (*a)[l]
		j++
		l++
	}

	for n <= h {
		workSpace[j] = (*a)[n]
		j++
		n++
	}

	fmt.Printf("workSpqce值:%v\n", workSpace)
	for j := 0; j < count; j++ {
		(*a)[low] = workSpace[j]
		low++
	}
}
快速排序

算法原理:选取一个基准值,不停把数组左边分为比基准值小的元素,右边分为比基准值大的元素,最终实现数组的排序.
时间复杂度: O( n ∗ log ⁡ 2 3 n*\log_{2}{3} nlog23)

func quickSort(arr *[6]int, low int, high int) {
	if low >= high {
		return
	} else {
		temp := arr[low]
		partition := partition(arr, low, high, temp)
		quickSort(arr, low, partition)
		quickSort(arr, partition+1, high)
	}
}

func partition(arr *[6]int, low int, high int, temp int) int {
	l, h := low, high
	for l < h {
		// 右边找到第一个比基准值小的元素
		for l < h && (*arr)[h] >= temp {
			h--
		}
		// 左边找到第一个比基准值大的元素
		for l < h && (*arr)[l] <= temp {
			l++
		}
		// 交换位置
		swap(arr, l, h)
	}
	(*arr)[low] = (*arr)[l]
	(*arr)[l] = temp
	return l
}

func swap(arr *[6]int, i int, j int) {
	temp := (*arr)[i]
	(*arr)[i] = (*arr)[j]
	(*arr)[j] = temp
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值