仓库码云地址
声明
本人是个菜鸟,不一定对哦。。。
我只测试一个是正确的。还有对于数组只有 一个数或者nil的不考虑。
先写一个公共的方法。替换俩个位置的数。
basicsort/tools.go
package basicsort func swap(arr []int, i int, j int) { temp := arr[i] arr[i] = arr[j] arr[j] = temp }
01 冒泡排序
俩俩比较,大的往后冒。
俩个for循环,每次循环排好一个最大的数
basicsort/01_bubble_sort.go
package basicsort //函数名首字母大写才能被其他包引用。 func Bubble_sort(arr []int) { //冒泡排序 for i := len(arr) - 1; i > 0; i-- { for j := 0; j <= i-1; j++ { if arr[j] > arr[j+1] { swap(arr, j, j+1) } } } }
- main.go 测试
package main import ( "fmt" "go-alg/basicsort" ) func main() { arr := []int{3, 2, 4, 5, 1, 6, 9, 8, 7, 0} basicsort.Bubble_sort(arr) fmt.Println(arr) }
02 选择排序
也是俩层for循环,也是俩俩比较。但是只是记录最大的索引,循环完之后。最大的索引和当前循环到的索引替换。
package basicsort func Select_sort(arr []int) { for i := len(arr) - 1; i > 0; i-- { currnet_max_index := i //记录当前循环最大的索引 for j := 0; j < i; j++ { if arr[j] > arr[currnet_max_index] { currnet_max_index = j } } swap(arr, i, currnet_max_index) //当前索引交换最大索引 } }
03 插入排序
就相当于打扑克,拿牌一样。前面都是已排好的序,新拿的牌从最后一张开始比较,直到找到自己插入的位置。
默认第一张是已排序。从第二张开始插入。
package basicsort func Insert_sort(arr []int) { for i := 1; i < len(arr); i++ { insert_value := arr[i] // 要插入的值 var j int // j要声明到for循环之外,这是最后确定要插入的索引位置。 python不需要。 for j = i - 1; j >= 0; j-- { if arr[j] > insert_value { arr[j+1] = arr[j] //当前牌往后移一个。直接赋值 } else { break } } arr[j+1] = insert_value //插入到指定位置,因为for循环有一个减一操作。所以这里应该是j+1才是要插入的位置 } }
04 希尔排序
优化的插入排序。插入排序的插入 步数是一个一个。希尔排序是一次就往前插好几个位置。慢慢回归到1. 加快 数快速移动到自己的位置。
一般是从 n/3 还是 n/2 开始 ,每次除2,慢慢到1.
多了个gap循环,插入排序多了个gap参数。每次插入比较 不是1而是gap了。
package basicsort func Shell_sort(arr []int) { for gap := len(arr) / 2; gap >= 1; gap /= 2 { Insert_sort_with_gap(arr, gap) } } func Insert_sort_with_gap(arr []int, gap int) { for i := 1; i < len(arr); i++ { insert_value := arr[i] // 要插入的值 var j int // j要声明到for循环之外,这是最后确定要插入的索引位置。 python不需要。 for j = i - gap; j >= 0; j -= gap { if arr[j] > insert_value { arr[j+gap] = arr[j] //当前牌往后移一个。直接赋值 } else { break } } arr[j+gap] = insert_value //插入到指定位置,因为for循环有一个减一操作。所以这里应该是j+gap才是要插入的位置 } }
05 归并排序
分而治之,
先划分到只有1个数的数组,然后俩俩合并。
是个递归函数。
会新增内存。
package basicsort import "fmt" func Merge_sort(arr []int) { if len(arr) <= 1 { return } mid := len(arr) / 2 left_arr := make([]int, len(arr[:mid])) right_arr := make([]int, len(arr[mid:])) copy(left_arr, arr[:mid]) copy(right_arr, arr[mid:]) fmt.Println("left_arr:", left_arr) fmt.Println("right_arr:", right_arr) Merge_sort(left_arr) // 左边数组排序 Merge_sort(right_arr) //右边数组排序 l := 0 // 左边数组的索引 r := 0 // 右边数组的索引 c := 0 // 原始数组的索引 // 开始合并左边数组和右边数组 for l < len(left_arr) && r < len(right_arr) { //比较当前俩个数组哪个小。 if left_arr[l] <= right_arr[r] { arr[c] = left_arr[l] l++ } else { arr[c] = right_arr[r] r++ } c++ } //走到这说明其中一个数组肯定没数了。把另一个数组的数依次合并到主数组 for l < len(left_arr) { arr[c] = left_arr[l] c++ l++ } for r < len(right_arr) { arr[c] = right_arr[r] c++ r++ } }
06 快速排序
也是递归和分而治之的思想
找一个基准数,把一个数组分成俩块,左边都是小于基准数,右边都是大于基准数的。
然后递归调用自己.
因数的顺序对时间复杂度影响较大。优化:每次随机选择基准数。
我做不到出来了;
package basicsort func Quick_sort2(arr []int) { help(arr, 0, len(arr)-1) } func help(arr []int, l int, r int) { if l < r { less, more := partation2(arr, l, r) help(arr, l, less-1) help(arr, more+1, r) } } func partation2(arr []int, l int, r int) (int, int) { less := l - 1 more := r for l < more { if arr[l] < arr[r] { less++ swap(arr, less, l) l++ } else if arr[l] > arr[r] { more-- swap(arr, more, l) } else { l++ } } swap(arr, more, r) return less + 1, more }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统