冒泡排序&快速排序&插入排序&堆排序-golang实现

1、冒泡排序

整体思路:从前向后,依次比较相邻元素的值,若发现逆序则交换,使值较大的元素从前向后移动
简而言之,第i趟排序将第i大的数据移向length-i-1位
时间复杂度:O(n^2) 稳定的排序算法

package main

import(
	"fmt"
)
func main(){
	arr := []int{7,5,4,8,9,6,10,1,11}
	// arr := []int{5,3,2}
	arr1 := bubble(arr)
	fmt.Println("排序后数组:", arr1)

}
func bubble(arr []int) []int{
	lens := len(arr)
	for i := 0; i < lens; i++ {
		for j := 0; j < lens-i-1; j++ {
			if arr[j] > arr[j+1]{
				tmp := arr[j+1]
				arr[j+1] = arr[j]
				arr[j] = tmp
			}
		}
		
	}
	return arr
}

2、快速排序

基本思想:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分所有数据都比另一部分所有数据小,再按此方法对这两部分数分别进行快排(递归),使整个数据变为有序序列
时间复杂度:O(nlogn) ,不稳定的排序算法

package main
import(
	"fmt"
)
func main(){
	arr := []int{7,5,4,12,78,8,9,6,10,1,11}
	// arr := []int{5,3,2}
	fmt.Println("排序前数组:", arr)
	arr1 := quickSortFunc(arr, 0, len(arr)-1)
	fmt.Println("排序后数组:", arr1)
}

func quickSortFunc(arr []int, start int, end int) []int{
	if start < end{
		i,j := start, end
		index := arr[(start+end)/2]
		for i<=j {
			for arr[j] > index{
				j--
			}
			for arr[i] < index{
				i++
			}
			if i <= j{
				arr[i],arr[j] = arr[j], arr[i]
				i++
				j--
			}
		}
		if start < j{ //向左递归
			quickSortFunc(arr, start, j)
		}
		if end > i {//向右递归
			quickSortFunc(arr, i, end)
		}
	}
	return arr
}


3、插入排序

基本思想:把n个待排序元素看成一个有序表和无序表,开始时有序表中只包含一个元素,无序表中包含n-1个元素,每次从无序表中取出第一个元素,把它与有序表元素依次进行比较,插入到有序表适当的位置,使之成为新的有序表
时间复杂度:O(n^2) , 稳定的排序算法

//插入排序
func insertSort(arr []int) []int {
	n := len(arr)
	for i := 1; i < n; i++ {
		insert := arr[i] //待插入的数
		j := i - 1
		if insert < arr[j] {
			for ; j >= 0 && arr[j] > insert; j-- {
				arr[j+1] = arr[j]
			}
			arr[j+1] = insert
		}
	}
	return arr
}

4、选择排序

现在有一堆乱序的数,比如:5 9 1 6 8 14 6 49 25 4 6 3。
第一轮迭代,从第一个数开始,左边到右边进行扫描,找到最小的数 1,与数列里的第一个数交换位置。
第二轮迭代,从第二个数开始,左边到右边进行扫描,找到第二小的数 3,与数列里的第二个数交换位置。
第三轮迭代,从第三个数开始,左边到右边进行扫描,找到第三小的数 4,与数列里的第三个数交换位置。
第N轮迭代:…
经过交换,最后的结果为:1 3 4 5 6 6 6 8 9 14 25 49,我们可以看到已经排好序了。
时间复杂度:O(n^2), 运行时间实际低于冒泡排序,不稳定的排序算法

func selectSort(arr []int) []int {
	n := len(arr)
	for i := 0; i < n; i++ {
		min := arr[i]
		minIndex := i
		for j := i + 1; j < n; j++ {
			if min > arr[j] {
				minIndex = j
				min = arr[j]
			}
		}
		if i != minIndex {
			arr[i], arr[minIndex] = arr[minIndex], arr[i]
		}
	}
	return arr
}

5、堆排序

根据灯神视频: https://www.bilibili.com/video/BV1Eb41147dK/?spm_id_from=333.1007.top_right_bar_window_custom_collection.content.click&vd_source=304ddde222ac891d9516a57f8192f02b

package main

import (
	"fmt"
)

func main() {
	tree := []int{2, 5, 3, 1, 10, 4}
	n := 6
	heapSort(tree, n)
	// buildHeap(tree, n)
	// heapify(tree, n, 0)
	fmt.Println(tree)
}

// n表示数组tree的长度,i表示对哪个节点做heapify
func heapify(tree []int, n int, i int) {
	if i >= n {
		return
	}
	//节点i的两个孩子节点
	c1 := 2*i + 1
	c2 := 2*i + 2
	max := i
	if c1 < n && tree[c1] > tree[max] {
		max = c1
	}
	if c2 < n && tree[c2] > tree[max] {
		max = c2
	}
	if max != i {
		tree[max], tree[i] = tree[i], tree[max]
		heapify(tree, n, max)
	}
}

func buildHeap(tree []int, n int) {
	last := n - 1
	//从最后一个parent节点依次向上做heapify,构造一个大顶堆
	parent := (last - 1) / 2
	for i := parent; i >= 0; i-- {
		heapify(tree, n, i)
	}

}
//堆排序
func heapSort(tree []int, n int) {
	buildHeap(tree, n) //先构造一个堆
	//从最后一个节点开始,依次和第0个节点交换
	for i := n - 1; i >= 0; i-- {
		tree[i], tree[0] = tree[0], tree[i]
		heapify(tree, i, 0) //砍断最后一个节点,做heapify
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值