Go:排序算法

一、冒泡排序

package main

import "fmt"

func BubbleSort(arr []int) {
	/*
	思路:将大的元素一步一步"冒泡"到最后
	*/
	l := len(arr)
	for i := 0; i < l-1; i++ {
		exchange := false
		for j := 0; j < l-1-i; j++ { // l-1 是因为只需要遍历到数组的倒数第二个元素,此时就可以拿这个元素和最后一个元素比较了
			if arr[j] > arr[j+1] {
				arr[j], arr[j+1] = arr[j+1], arr[j]
				exchange = true
			}
		}
		if !exchange {
			return
		}
	}
}

func main() {
	arr := []int{5, 17, 1, 68, 22}
	fmt.Println("排序前:", arr)
	BubbleSort(arr)
	fmt.Println("排序后:", arr)
}

二、选择排序

package main

import "fmt"

func SelectSort(arr []int) {
	/*
	思路:
		1.把第一个没有排序过的元素设置为最小值
		2.遍历每个没有排序过的元素
			如果元素 < 现在的最小值
			将此元素设置成为新的最小值
		3.经过步骤2后,如果最小值发生改变,则将最小值和第一个没有排序过的位置交换
	*/
	l := len(arr)
	for i := 0; i < l-1; i++ {     // l-1 是因为最后一个元素不需要比较了
		/*
		无序区间:
			第一次:[0, l-1]
			第二次:[1, l-1]
			...
		*/
		minIndex := i // 记录最小值的索引
		for j := i+1; j < l; j++ { // i+1 表示自己不用跟自己比
			if arr[j] < arr[minIndex] {
				minIndex = j 	   // 更新最小值索引
			}
		}
		if i != minIndex {         // i 不是最小值时,将 i 和最小值进行交换
			arr[i], arr[minIndex] = arr[minIndex], arr[i]
		}
	}
}

func main(){
	arr := []int{5, 17, 1, 68, 22}
	fmt.Println("排序前:", arr)
	SelectSort(arr)
	fmt.Println("排序后:", arr)
}

三、插入排序

package main

import "fmt"

func InsertSort(arr []int) {
	/*
	思路:
		1.将第一个元素标记为已排序
		2.遍历每个没有排序过的元素,将每次遍历的第一个元素用临时变量保存
			因为:
				第一次遍历从索引 1 开始
				第二次遍历从索引 2 开始
			所以:
				设遍历索引为 i (从1开始),则临时变量保存的元素是 arr[i]
		3.如果排序过的最后一个元素 > 临时保存的元素,则将排序过的元素向右移一格;否则,插入这个临时保存的元素
	*/
	l := len(arr)
	for i := 1; i < l; i ++ {	  // i = [1, 2, 3... l-1]
		temp := arr[i] 			  // temp用来保存未排序序列的第一个元素
		prevIndex := i - 1 		  // 已排序序列的最后一个元素索引
		for ; prevIndex >=0 && arr[prevIndex] > temp; {
			arr[prevIndex + 1] = arr[prevIndex] // 右移
			prevIndex -= 1 		  // 右移过后,temp还要和有序序列的每个元素从后向前依次比较,所以 prevIndex 自减 1
		}
		arr[prevIndex + 1] = temp // 经过上面的循环右移,直到条件不满足,则将 temp 插入索引为 prevIndex 元素的后面
	}
}

func main() {
	arr := []int{5, 17, 1, 68, 22}
	fmt.Println("排序前:", arr)
	InsertSort(arr)
	fmt.Println("排序后:", arr)
}

四、快速排序

package main

import "fmt"

func QuickSort(arr []int) {
	quickSort(arr, 0, len(arr)-1)
}

func quickSort(arr []int, left, right int) []int {
	if left < right {
		partitionIndex := partition(arr, left, right)
		quickSort(arr, left, partitionIndex-1)
		quickSort(arr, partitionIndex+1, right)
	}
	return arr
}

func partition(arr []int, left, right int) int {
	temp := arr[left] // 基准(pivot)元素
	for ; left < right; {
		// 从序列右边往左边找,直到找到比基准小的元素才退出循环
		for ; left < right && arr[right] >= temp; {
			right -= 1
		}
		arr[left] = arr[right] // 将这个元素"左移"
		// 从序列左边往右边找,直到找到比基准大的元素才退出循环
		for ; left < right && arr[left] <= temp; {
			left += 1
		}
		arr[right] = arr[left] // 将这个元素"右移"
	}
	arr[left] = temp // 相当于将基准元素放到"中间",此时基准元素左边都是小于基准元素的元素,右边同理
	return left
}

func main() {
	arr := []int{5, 17, 1, 68, 22}
	fmt.Println("排序前:", arr)
	QuickSort(arr)
	fmt.Println("排序后:", arr)
}

 

posted @ 2019-10-06 11:05  就俗人一个  阅读(315)  评论(0编辑  收藏  举报