package mainimport ("fmt"
)func main() {//保存需要排序的Slicearr := []int{9, 3, 3, 4, 7, 2, 4, 7, 2, 1, 4, 7, 2, 11, 12, 11, 18, 19, 12,3, 4, 7, 2, 1, 0, 11, 12, 11, 13, 4, 7, 2, 1, 0, 11, 12, 11, 18,0,1,0,1}//实际用于排序的Slicelist := make([]int, len(arr))copy(list, arr)QuickSort(list)fmt.Println("快速排序:\t", list)copy(list, arr)QuickSortX(list)fmt.Println("快速排序X:\t", list)copy(list, arr)list = MergeSort(list)fmt.Println("二路归并排序:\t", list)copy(list, arr)BubbleSort(list)fmt.Println("冒泡排序:\t", list)copy(list, arr)BubbleSortX(list)fmt.Println("冒泡排序X:\t", list)copy(list, arr) //将arr的数据覆盖到list,重置listInsertSort(list)fmt.Println("直接插入排序:\t", list)copy(list, arr)ShellSort(list)fmt.Println("希尔排序:\t", list)copy(list, arr)SelectSort(list)fmt.Println("简单选择排序:\t", list)copy(list, arr)HeapSort(list)fmt.Println("堆排序:     \t", list)}//region 快速排序
/*
步骤:
1.从数列中挑出一个元素作为基准数
2.分区过程,将比基准数大的放到右边,小于或等于它的数都放到左边。(每次归位一个基准数到它最终应该在的位置)
3.再对左右区间递归执行第二步,直至各区间只有一个数
PS:
快速排序里面比较精妙,要注意基准数的选择和哨兵指针移动的先后顺序
*/
func QuickSort(list []int) {if len(list) <= 1 {return}var low int = 0var high int = len(list) - 1//以list[0]为基准数for low < high {if list[high] >= list[0] {high--continue}if list[low] <= list[0] {low++continue}list[low], list[high] = list[high], list[low]}//low == highif list[low] < list[0] {list[low], list[0] = list[0], list[low]}QuickSort(list[:low])QuickSort(list[low+1:])
}func QuickSortX(list []int) {if len(list) <= 1 {return}key, i := list[0], 1low, high := 0, len(list)-1for low < high {if list[i] > key {list[i], list[high] = list[high], list[i]high--} else {list[i], list[low] = list[low], list[i]low++i++}}QuickSortX(list[:low])QuickSortX(list[low+1:])
}
//endregion//region 二路归并排序
/*
步骤:
1.将待排序序列R[0...n-1]看成是n个长度为1的有序序列,将相邻的有序表成对归并,得到n/2个长度为2的有序表;
2.将这些有序序列再次归并,得到n/4个长度为4的有序序列;
3.如此反复进行下去,最后得到一个长度为n的有序序列。归并排序其实要做两件事:
(1)“分解”——将序列每次折半划分。
(2)“合并”——将划分后的序列段两两合并后排序。
*/
func MergeSort(list []int) []int {   //着重理解该函数if len(list) <= 1 {return list} mid := len(list)/2left := MergeSort(list[:mid])right := MergeSort(list[mid:])return merge(left,right)
}func merge(left, right []int) (result []int) {i,j := 0,0for 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
}
//endregion//region 冒泡排序
/*
步骤:
1.比较相邻的元素。如果第一个比第二个大,就交换他们两个
2.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数
3.针对所有的元素重复以上的步骤,除了最后一个
4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较
*/
func BubbleSort(list []int) {for i := 0; i < len(list)-1; i++ {for j := 0; j < len(list)-i-1; j++ {if list[j] > list[j+1] {list[j], list[j+1] = list[j+1], list[j]}}}
}//优化:如果没有交换发生,代表已经有序,即可结束
func BubbleSortX(list []int) {var exchange bool = falsefor i := 0; i < len(list)-1; i++ {for j := 0; j < len(list)-i-1; j++ {if list[j] > list[j+1] {list[j], list[j+1] = list[j+1], list[j]exchange = true}}if !exchange {break}exchange = false}}
//endregion//region 插入排序
/*
步骤:
1.从第一个元素开始,该元素可以认为已经被排序
2.取出下一个元素,在已经排序的元素序列中从后向前扫描
3.如果被扫描的元素(已排序)大于新元素,将该元素后移一位
4.重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
5.将新元素插入到该位置后
6.重复步骤2~5
*/
func InsertSort(list []int) {var temp, i, j intfor i = 1; i < len(list); i++ {temp = list[i]for j = i - 1; j >= 0 && temp < list[j]; j-- {list[j+1] = list[j]}list[j+1] = temp}
}//region 希尔排序
/*
基本思想:
把记录按步长 gap 分组,对每组记录采用直接插入排序方法进行排序。
随着步长逐渐减小,所分成的组包含的记录越来越多,当步长的值减小到 1 时,整个数据合成为一组,构成一组有序记录,则完成排序。
*/
func ShellSort(list []int) {for gap := (len(list) + 1) / 2; gap >= 1; gap = gap / 2 {for i := 0; i+gap < len(list); i++ {InsertSort(list[i : i+gap+1])}}
}
//endregion//region 简单选择排序
/*
步骤:
1.在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
2.再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
3.以此类推,直到所有元素均排序完毕。
*/
func SelectSort(list []int) {var index intfor i := 0; i < len(list)-1; i++ {index = ifor j := i + 1; j < len(list); j++ {if list[index] > list[j] {index = j}}list[index], list[i] = list[i], list[index]}
}
//endregion//region 堆排序
/*
步骤:
1.构造最大堆(Build_Max_Heap):若数组下标范围为0~n,考虑到单独一个元素是大根堆,则从下标n/2开始的元素均为大根堆。
于是只要从n/2-1开始,向前依次构造大根堆,这样就能保证,构造到某个节点时,它的左右子树都已经是大根堆。2.堆排序(HeapSort):由于堆是用数组模拟的。得到一个大根堆后,数组内部并不是有序的。因此需要将堆化数组有序化。
思想是移除根节点,并做最大堆调整的递归运算。第一次将heap[0]与heap[n-1]交换,再对heap[0...n-2]做最大堆调整。
第二次将heap[0]与heap[n-2]交换,再对heap[0...n-3]做最大堆调整。重复该操作直至heap[0]和heap[1]交换。
由于每次都是将最大的数并入到后面的有序区间,故操作完后整个数组就是有序的了。3.最大堆调整(Max_Heapify):该方法是提供给上述两个过程调用的。目的是将堆的末端子节点作调整,使得子节点永远小于父节点 。
*/
func heapAdjust(list []int, parent int, length int) {temp := list[parent]  // temp保存当前父节点child := 2*parent + 1 // 先获得左孩子for child < length {// 如果有右孩子结点,并且右孩子结点的值大于左孩子结点,则选取右孩子结点if child+1 < length && list[child] < list[child+1] {child++}// 如果父结点的值已经大于孩子结点的值,则直接结束if temp >= list[child] {break}// 把孩子结点的值赋给父结点list[parent] = list[child]// 选取孩子结点的左孩子结点,继续向下筛选parent = childchild = 2*child + 1}list[parent] = temp
}func HeapSort(list []int) {// 循环建立初始堆for i := len(list) / 2; i >= 0; i-- {heapAdjust(list, i, len(list)-1)}// 进行n-1次循环,完成排序for i := len(list) - 1; i > 0; i-- {// 最后一个元素和第一元素进行交换list[0], list[i] = list[i], list[0]// 筛选 R[0] 结点,得到i-1个结点的堆heapAdjust(list, 0, i)}
}
//endregion

 本文更新地址:HopeHook.com 

转载于:https://www.cnblogs.com/achst/p/4985983.html

内部排序算法(Golang版本)相关推荐

  1. 内部排序算法全面总结

    排序的概念 排序,就是重新排列表中的元素,使表中的元素按照关键字有序的过程. 我所了解的 表 多半是顺序表,因为顺序表实现较为简单,但是链表结构同样可以实现很多排序算法. 定义中的元素一般指什么元素呢 ...

  2. 九大内部排序算法(快速排序、归并排序、堆排序、希尔排序、基数排序)

    排序(Sorting)是计算机程序设计中的一种重要操作,它的功能是将一个数据元素(或记录)的任意序列,重新排列成一个按关键字有序的序列. 文章目录 由于待排序的记录数量不同,使得排序过程中涉及的存储器 ...

  3. 超详细!各种内部排序算法的比较

    先来个表格总结直观展示下: 各种内部排序算法的性质            算法种类                    时间复杂度  空间复 杂度 稳定性 最好情况 平均情况 最坏情况 插入排序 直 ...

  4. 飞鸽传书内部排序算法的性能比较

    部排序算法的性能比较 飞鸽传书内部排序算法的性能比较 1)排序的稳定性及分析: 假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,ri=r ...

  5. 数据结构之排序算法:内部排序算法的应用与比较

    排序算法:内部排序算法的应用与比较 思维导图: 比较: 应用: 思维导图: 比较: 应用:

  6. 数据结构之内部排序算法总结笔记

    内部排序算法  排序的基本概念: 把一组无序的数据元素按照关键字值递增(或递减)的顺序重新排列.  一.插入排序 思想:将序列分为[有序段]与[无序段]两段,然后依次将[无序段]中的元素插入到[有序段 ...

  7. 《数据结构》--内部排序算法比较

    题目 各种内部排序算法的时间复杂度分析结果只给出了算法执行时间的阶,或大概执行时间.试通过随机的数据比较各算法的关键字比较次数和关键字移动次数,以取得直观感受. 基本要求: (1) 从以下常用的内部排 ...

  8. 内部排序算法比较-数据结构C语言课设

    名称:内部排序算法比较 内容:在教科书中,各种内部排序算法的时间复杂的分析结果只给出了算法执行时间的阶,或大概执行时间.试通过随机数据比较各种算法的关键字比较次数和关键字移动次数,以取得直观感受. 任 ...

  9. 《内部排序算法比较》

    <内部排序算法比较> 一.[问题描述] 在教科书中,各种内部排序算法的时间复杂度分析结果只给出算法的大致执行时间.试通过随机数据比较各算法的关键字比较次数和关键字移动次数,以获得直观感受 ...

  10. 《数据结构》之内部排序算法比较

    前言 各种内部排序算法的时间复杂度分析结果只给出了算法执行时间的阶,或大概执行时间.试通过随机的数据比较各算法的关键字比较次数和关键字移动次数,以取得直观感受. 基本要求: (1) 从以下常用的内部排 ...

最新文章

  1. 王者荣耀中一个英雄是怎么被产生的?
  2. 【转】为什么要写技术博,写在前面的话
  3. 【转自聊聊架构公众号】 Redis大key图形化统计及展示
  4. vector邻接表建图+DFS+BFS
  5. 动漫风html源码,CSS3动画制作一个卡通风格的404错误页面代码
  6. access exex控制pc_ownCloud/Nextcloud文件访问控制(Files Access Control)
  7. Android开发p图软件,媲美大神P图效果 Android软件抠图神手
  8. 怎么看软件的编写代码
  9. Java函数中改变变量值
  10. DevOps团队如何选择监控工具
  11. C语言考试知识点汇总(理论知识点)
  12. ubuntu里面控制器放大缩小屏幕
  13. 软件测试面试必问问题
  14. 多分支表达-倍数问题
  15. 因违反《竞业协议》,三年白忙活了!赔偿 97.6 万元,返还 15.8 万元
  16. 基于OpenCV实现二维码发现与定位
  17. 安卓疫情打卡APP源码
  18. 时间复杂度的三种常见表示符号
  19. 如何使用FFmpeg的解码器
  20. 昨晚我遇到了超级网红 区块链本人

热门文章

  1. 数据挖掘原理与算法_古今争翘,一首机器学习与数据挖掘神曲,共11.99G送你直上云霄...
  2. 【CF-gym101889:J】Jumping frog(圆上跳----思维)
  3. 【UVA10976】Fractions Again?!(结构体内重载运算符---水题)
  4. MATLAB--黄金分割法
  5. OpenCV(二)---朴素贝叶斯分类器 NormalBayesClassifier
  6. 极客大学产品经理训练营 产品文档和原型 第7课总结
  7. 编程的未来 Java, C, Go, Swift, Dart? Uncle Bob Martin - The Future of Programming
  8. android 控件xpath软件_请像用户使用软件一样,享受自动化测试~
  9. 鸿蒙官网首页,鸿蒙官网-鸿蒙手游官网首页最新版预约 v1.0-优盘手机站
  10. 发布传参_Taro 1.2.9 发布,BAT 小程序、H5 与 RN 端统一框架