go常见排序算法

简介

冒泡排序:两两比较相邻的数,如果反序则进行交换,知道没有反序为止,冒泡排序是一种稳定的排序算法。
选择排序:通过不断交换,每次遍历在n-i+1中选取数字最小的作为有序排列的第i个数,就是将每一趟最小的和第i进行交换。选择排序是一种稳定的排序算法。
插入排序:将一个数组分为有序和无须,将一个数插入到已经排好序的有序数组中,从而达到最终的排序。插入排序是一种稳定的排序算法。
希尔排序:希尔排序是在选择排序基础上改进的,希尔排序将一个数组分割成若干个子序列,然后对每个子序列进行插入排序,当每个子序列都基本有序时,最后在进行一次插入排序。主要将相聚某个增量的数组成一个子序列,这样就能保证在子序列内分别进行插入排序;希尔排序是不稳定的排序算法。
堆排序:每个节点的值大于或等于左右节点的称为大顶堆,每个节点值小于或等于左右节点的称为小顶堆。将待排序的数组构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点,然后将其与堆数组的末尾元素交换,此时末尾元素就是最大值,然后将剩余n-1个数重新构造成一个堆,如此反复。堆排序不是稳定的排序算法。
归并排序:将数组看成n个有序的子序列,每个子序列的长度为1,然后两两归并,得到n/2个长度为2或1的有序子序列,在两两归并,如此重复,直到长度为n的有序序列为止。归并排序是一种稳定的排序算法。
快速排序:通过一趟排序将带排序记录分割成独立的两部分,其中一部分的数比另一部分数小,则可分别对这两部分数继续排序。

复杂度

平均情况最好情况最坏情况辅助空间
冒泡排序O(n^2)O(n)O(n^2)O(1)
选择排序O(n^2)O(n)O(n^2)O(1)
插入排序O(n^2)O(n)O(n^2)O(1)
希尔排序O(nlogn)~O(n^2)O(n^1.3)O(n^2)O(1)
堆排序O(nlogn)O(nlogn)O(nlogn)O(1)
归并排序O(nlogn)O(nlogn)O(nlogn)O(n)
快速排序O(nlogn)O(nlogn)O(n^2)O(logn)~O(n)

冒泡排序

func mp1(nums []int) {
	n := len(nums)
	for i := 0; i < n; i++ {
		for j := i + 1; j < n; j++ {
			if nums[j] < nums[i] {
				nums[i], nums[j] = nums[j], nums[i]
			}
		}
	}
	fmt.Println("冒泡1:", nums)
}

冒泡排序改进版

func mp2(nums []int) {
	n := len(nums)
	for i := 0; i < n; i++ {
		for j := n - 2; j >= 0; j-- {
			if nums[j] > nums[j+1] {
				nums[j], nums[j+1] = nums[j+1], nums[j]
			}
		}
	}
	fmt.Println("冒泡2:", nums)
}

选择排序

func xz(nums []int) {
	n := len(nums)
	for i := 0; i < n; i++ {
		min := i
		for j := i + 1; j < n; j++ {
			if nums[min] > nums[j] {
				min = j
			}
		}
		if min != i {
			nums[i], nums[min] = nums[min], nums[i]
		}
	}
	fmt.Println("选择:  ", nums)
}

插入排序

func cr(nums []int) {
	n := len(nums)
	for i := 1; i < n; i++ {
		tmp := nums[i]
		j := i - 1
		for ; j >= 0 && tmp < nums[j]; j-- {
			nums[j+1] = nums[j]
		}
		if j+1 != i {
			nums[j+1] = tmp
		}
	}
	fmt.Println("插入排序:", nums)
}

希尔排序

func xe(nums []int) {
	n := len(nums)
	incr := n
	for incr > 0 {
		incr = incr / 3
		for i := incr; i < n; i++ {
			tmp := nums[i]
			j := i - incr
			for ; j >= 0 && tmp < nums[j]; j -= incr {
				nums[j+incr] = nums[j]
			}
			if j+incr != i {
				nums[j+incr] = tmp
			}
		}
	}
	fmt.Println("希尔排序:", nums)
}

归并排序

func gb(nums []int) {
	msort(nums, 0, len(nums)-1)
	fmt.Println("归并:  ", nums)
}
func msort(nums []int, left, right int) {
	mid := 0
	tmp := make([]int, len(nums))
	if left < right {
		mid = (left + right) / 2
		msort(nums, left, mid)
		msort(nums, mid+1, right)
		merge(tmp, nums, left, mid, right)
	}
}
func merge(tmp, nums []int, left, mid, right int) {
	l := left
	r := mid + 1
	k := left
	for ; l <= mid && r <= right; k++ {
		if nums[l] < nums[r] {
			tmp[k] = nums[l]
			l++
		} else {
			tmp[k] = nums[r]
			r++
		}
	}
	for ; l <= mid; l++ {
		tmp[k] = nums[l]
		k++
	}
	for ; r < right; r++ {
		tmp[k] = nums[r]
		k++
	}
	for left < k {
		nums[left] = tmp[left]
		left++
	}
}

大顶堆

func swap(a, b *int) {
	*a, *b = *b, *a
}
func maxHeap(nums []int) {
	n := len(nums)
	for i := n; i > 1; i-- {
		createHeap(nums, i)
		swap(&nums[0], &nums[i-1])
	}
	fmt.Println("大顶堆排序2:", nums)
}
func createHeap(nums []int, n int) {
	for i := n/2 - 1; i >= 0; i-- {
		heapAdjust(nums, i, n)
	}
}
func heapAdjust(nums []int, m, n int) {
	max := m
	l := m*2 + 1
	r := m*2 + 2

	if l < n && nums[l] < nums[max] {
		max = l
	}
	if r < n && nums[r] < nums[max] {
		max = r
	}
	if m != max {
		swap(&nums[m], &nums[max])
		heapAdjust(nums, m, n)
	}
}

小顶堆

func swap(a, b *int) {
	*a, *b = *b, *a
}
func minHeap(nums []int) {
	n := len(nums)
	for i := n; i > 1; i-- {
		CreateHeap(nums, i)
		swap(&nums[0], &nums[i-1])
	}
	fmt.Println("小顶堆排序:", nums)
}
func CreateHeap(nums []int, n int) {
	for i := n/2 - 1; i >= 0; i-- {
		HeapAdjust(nums, i, n)
	}
}
func HeapAdjust(nums []int, m int, n int) {
	min := m
	l := m*2 + 1
	r := m*2 + 2
	if l < n && nums[l] > nums[min] {
		min = l
	}
	if r < n && nums[r] > nums[min] {
		min = r
	}
	if m != min {
		swap(&nums[m], &nums[min])
		HeapAdjust(nums, m, n)
	}
}

快速排序

func swap(a, b *int) {
	*a, *b = *b, *a
}
func quickSort(nums []int) {
	qsort(nums, 0, len(nums)-1)
	fmt.Println("快速排序:", nums)
}
func qsort(nums []int, left, right int) {
	if left < right {
		p := partition(nums, left, right)
		qsort(nums, left, p)
		qsort(nums, p+1, right)
	}
}
func partition(nums []int, left, right int) int {
	tmp := nums[left]
	for left < right {
		for left < right && nums[right] > tmp {
			right--
		}
		swap(&nums[left], &nums[right])
		for left < right && nums[left] < tmp {
			left++
		}
		swap(&nums[left], &nums[right])
	}
	return left
}

案例

求topk

func topK(nums []int, k int) {
	res := Qsort(nums, 0, len(nums)-1, k)
	fmt.Println(res, nums[:k])
}

func Qsort(nums []int, left, right, k int) int {
	// n := len(nums)
	for {
		indx := Partition(nums, left, right)
		if indx == k-1 {
			return nums[indx]
		} else if indx < k-1 {
			left = indx + 1
		} else {
			right = indx - 1
		}
	}
}
func Partition(nums []int, left, right int) int {
	tmp := nums[left]
	for left < right {
		for left < right && nums[right] <= tmp {
			right--
		}
		nums[left] = nums[right]
		for left < right && nums[left] >= tmp {
			left++
		}
		nums[right] = nums[left]
	}
	nums[left] = tmp
	return left
}

最大的k个数

func q1(nums []int, k int) {
	q2(nums, 0, len(nums)-1, k)
	fmt.Println(nums[:k])
}

func q2(nums []int, left, right, k int) {
	m := q3(nums, left, right)
	num := m - left + 1
	if k < num {
		q2(nums, left, m-1, k)
	} else if k > num {
		q2(nums, m+1, right, k-num)
	}
}
func q3(nums []int, left, right int) int {
	tmp := nums[right]
	i := left - 1
	for j := left; j < right; j++ {
		if nums[j] >= tmp { //改成<=就是求最小的k个数
			i++
			nums[i], nums[j] = nums[j], nums[i]
		}
	}
	nums[i+1], nums[right] = nums[right], nums[i+1]
	return i + 1
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 很抱歉,由于篇幅限制,我不能在这里提供七个排序算法的完整 Golang 代码。但是,我可以简述每种算法的实现思路,并给出部分代码: 1. 冒泡排序:比较相邻的两个数,如果第一个数比第二个数大,就交换它们两个。对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该是最大的数。针对所有的元素重复以上的步骤,除了最后一个。持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。 ``` func BubbleSort(arr []int) { n := len(arr) for i := 0; i < n-1; i++ { for j := 0; j < n-i-1; j++ { if arr[j] > arr[j+1] { arr[j], arr[j+1] = arr[j+1], arr[j] } } } } ``` 2. 选择排序:首先在未排序的数列中找到最小元素,然后将其存放到数列的起始位置。接着,再从剩余未排序的元素中继续寻找最小元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。 ``` func SelectSort(arr []int) { n := len(arr) ### 回答2: 以下是七大排序算法Golang代码: 1. 冒泡排序(Bubble Sort): ``` func BubbleSort(arr []int) { length := len(arr) for i := 0; i < length-1; i++ { for j := 0; j < length-1-i; j++ { if arr[j] > arr[j+1] { arr[j], arr[j+1] = arr[j+1], arr[j] } } } } ``` 2. 选择排序(Selection Sort): ``` func SelectionSort(arr []int) { length := len(arr) for i := 0; i < length-1; i++ { minIndex := i for j := i+1; j < length; j++ { if arr[j] < arr[minIndex] { minIndex = j } } arr[i], arr[minIndex] = arr[minIndex], arr[i] } } ``` 3. 插入排序(Insertion Sort): ``` func InsertionSort(arr []int) { length := len(arr) for i := 1; i < length; i++ { key := arr[i] j := i - 1 for j >= 0 && arr[j] > key { arr[j+1] = arr[j] j-- } arr[j+1] = key } } ``` 4. 希尔排序(Shell Sort): ``` func ShellSort(arr []int) { length := len(arr) gap := 1 for gap < length/3 { gap = gap*3 + 1 } for gap > 0 { for i := gap; i < length; i++ { temp := arr[i] j := i - gap for j >= 0 && arr[j] > temp { arr[j+gap] = arr[j] j -= gap } arr[j+gap] = temp } gap = gap / 3 } } ``` 5. 归并排序(Merge Sort): ``` func MergeSort(arr []int) []int { if len(arr) <= 1 { return arr } mid := len(arr) / 2 left := MergeSort(arr[:mid]) right := MergeSort(arr[mid:]) return merge(left, right) } func merge(left, right []int) []int { var result []int for len(left) > 0 && len(right) > 0 { if left[0] <= right[0] { result = append(result, left[0]) left = left[1:] } else { result = append(result, right[0]) right = right[1:] } } result = append(result, left...) result = append(result, right...) return result } ``` 6. 快速排序(Quick Sort): ``` func QuickSort(arr []int) { quickSortHelper(arr, 0, len(arr)-1) } func quickSortHelper(arr []int, low, high int) { if low < high { pivot := partition(arr, low, high) quickSortHelper(arr, low, pivot-1) quickSortHelper(arr, pivot+1, high) } } func partition(arr []int, low, high int) int { pivot := arr[high] i := low - 1 for j := low; j < high; j++ { if arr[j] < pivot { i++ arr[i], arr[j] = arr[j], arr[i] } } arr[i+1], arr[high] = arr[high], arr[i+1] return i + 1 } ``` 7. 堆排序(Heap Sort): ``` func HeapSort(arr []int) { size := len(arr) for i := size/2 - 1; i >= 0; i-- { heapify(arr, size, i) } for i := size - 1; i > 0; i-- { arr[i], arr[0] = arr[0], arr[i] heapify(arr, i, 0) } } func heapify(arr []int, size int, root int) { largest := root left := 2 * root + 1 right := 2 * root + 2 if left < size && arr[left] > arr[largest] { largest = left } if right < size && arr[right] > arr[largest] { largest = right } if largest != root { arr[root], arr[largest] = arr[largest], arr[root] heapify(arr, size, largest) } } ``` 希望这些代码能帮助你了解每个排序算法的实现。 ### 回答3: 下面是七种常见排序算法Golang代码实现: 1. 冒泡排序: ```go func bubbleSort(arr []int) { n := len(arr) for i := 0; i < n-1; i++ { for j := 0; j < n-i-1; j++ { if arr[j] > arr[j+1] { arr[j], arr[j+1] = arr[j+1], arr[j] } } } } ``` 2. 选择排序: ```go func selectionSort(arr []int) { n := len(arr) for i := 0; i < n-1; i++ { minIndex := i for j := i + 1; j < n; j++ { if arr[j] < arr[minIndex] { minIndex = j } } arr[i], arr[minIndex] = arr[minIndex], arr[i] } } ``` 3. 插入排序: ```go func insertionSort(arr []int) { n := len(arr) for i := 1; i < n; i++ { key := arr[i] j := i - 1 for j >= 0 && arr[j] > key { arr[j+1] = arr[j] j-- } arr[j+1] = key } } ``` 4. 归并排序: ```go func mergeSort(arr []int) []int { if len(arr) <= 1 { return arr } mid := len(arr) / 2 left := mergeSort(arr[:mid]) right := mergeSort(arr[mid:]) return merge(left, right) } func merge(left, right []int) []int { result := make([]int, 0) i, j := 0, 0 for i < len(left) && j < len(right) { if left[i] < right[j] { result = append(result, left[i]) i++ } else { result = append(result, right[j]) j++ } } result = append(result, left[i:]...) result = append(result, right[j:]...) return result } ``` 5. 快速排序: ```go func quickSort(arr []int, low, high int) { if low < high { pivot := partition(arr, low, high) quickSort(arr, low, pivot-1) quickSort(arr, pivot+1, high) } } func partition(arr []int, low, high int) int { pivot := arr[high] i := low - 1 for j := low; j < high; j++ { if arr[j] < pivot { i++ arr[i], arr[j] = arr[j], arr[i] } } arr[i+1], arr[high] = arr[high], arr[i+1] return i + 1 } ``` 6. 堆排序: ```go func heapSort(arr []int) { n := len(arr) for i := n/2 - 1; i >= 0; i-- { heapify(arr, n, i) } for i := n - 1; i > 0; i-- { arr[0], arr[i] = arr[i], arr[0] heapify(arr, i, 0) } } func heapify(arr []int, n, i int) { largest := i left := 2*i + 1 right := 2*i + 2 if left < n && arr[left] > arr[largest] { largest = left } if right < n && arr[right] > arr[largest] { largest = right } if largest != i { arr[i], arr[largest] = arr[largest], arr[i] heapify(arr, n, largest) } } ``` 7. 计数排序: ```go func countingSort(arr []int) []int { max := 0 for _, num := range arr { if num > max { max = num } } count := make([]int, max+1) for _, num := range arr { count[num]++ } sortedArr := make([]int, 0, len(arr)) for i, c := range count { for c > 0 { sortedArr = append(sortedArr, i) c-- } } return sortedArr } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值