算法相关-经典排序算法(goland实现)

2023-11-19

概述

  • 插入排序

    将未排序的元素同已排序的元素从后往前比较,带排序元素:a,被比较元素:b,如果a<b则, swap(a,)

  • 快速排序

    每趟排序把基准值放到对的位置即左边的元素都比它小,右边的元素都比它大

  • 冒泡排序

    每一趟排序(包括多次两两比较和交换)找出余下的最大元素放在数组的最后,叫沉底排序更贴切。

  • 选择排序

    对未排序的元素找出最小的元素, 放到未排序数组的0号位置

  • 希尔排序

    插入排序的改进;插入排序比较移动的步长是1,希尔排序中改进该步长,从大缩小到1

  • 堆排序

    利用大顶堆的特点:根的值比左右子树都大

    先构造大顶堆

    交换堆的第一个元素和最后一个元素,使最大的元素放在数组的最后,再对前面的堆进行调整,重复该操作

  • 归并排序

    递归地合并两个有序数组 ,不断一分为二拆分数组,当左右数组长度为1时,开始排序并合并,之后对合并后的数组(已排序)继续归并排序,采用分而治之的思想

1. 冒泡排序

每一趟排序(包括多次两两比较和交换)找出余下的最大元素放在数组的最后,叫沉底排序更贴切

func swap(arr *[]int, i, j int) {
   temp := (*arr)[i]
   (*arr)[i] = (*arr)[j]
   (*arr)[j] = temp
}

func bubble(nums []int) []int {
   lgh := len(nums)
   for i := 0; i < lgh-1; i++ {
      for j := 0; j < lgh-i-1; j++ {
         if nums[j] > nums[j+1] {
            swap(&nums, j, j+1)
         }
      }
   }
   return nums
}

2.选择排序

  • 时间复杂度 O(n^2),空间复杂度 O(1)
  • 对未排序的元素找出最小的元素, 放到未排序数组的0号位置
func selectSort(nums []int)  []int{
	lgh:=len(nums)
	for i:=0;i<lgh-1;i++{
		for j:=i+1;j<lgh;j++{
			if nums[j] < nums[i]{
				swap(&nums[j], &nums[i])
			}
		}
	}
	return nums
}
func swap(v1, v2 *int){
	*v1, *v2 = *v2, *v1
}

3.插入排序

每一趟排序把本次排序的元素往前插入到合适的位置

func insertSort(nums []int) []int {
	lgh := len(nums)
	for i:=1;i< lgh;i++{
		for j:=i-1;j>=0;j--{
			if nums[j+1] < nums[j]{
				swap(&nums[j+1], &nums[j])
				continue
			}
			//fmt.Println(nums)
			break
		}
	}
	return nums
}

func swap(v1 *int, v2 *int) {
	*v1, *v2 = *v2, *v1
}

4.希尔排序

原理

希尔排序,就是按某个增量值对数据进行分组,每组单独排序好后,再缩小这个增量,然后按新增量对数据分组后每个分组再各自排序。最终增加缩小到1的时候,排序结束。所以希尔排序又叫缩小增量排序(Diminishing Increment Sort)

关于增量

最佳增量值的选择其实是个数学难题,有兴趣的可以自己搜下相关资料。

常用的增量有 n/2(这个又叫希尔增量)、n/3、2^k-1(hibbard增量)等,实际使用中稍微改版增量也可能使排序的性能产生很大的波动。

比如使用n/2的增量,就是初始增量就是 length/2 ,第二轮分组时就再除2:length/4,直至增量值变成1

流程

假设有个数组:[8,12,6,33,12,5,4,94,63,23,75,22,43,27,46],以n/2为增量,那么整个排序流程就是这样的:

[golang] 数据结构-希尔排序

复杂度

不同增量复杂度不同。n/2时平均的时间复杂度为O(n^2)。

相较直接插入排序,希尔排序减少了比较和交换的次数,在中小规模的排序中,性能表现较好。但随着数据量增大,希尔排序与其他更好的排序算法(快排、堆排、并归等)仍有较大差距。

作者:holdtom
链接:https://www.imooc.com/article/271234
来源:慕课网

基本思想

先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序 待整个序列中的记录“基本有序”时 再对全体记录进行依次直接插入排序

插入排序的改进;插入排序比较移动的步长是1,希尔排序中改进该步长,从大缩小到1

在这里插入图片描述


func shell(nums []int) []int {
	lgh := len(nums)
	// 这里就以n/2为增量

	gap := lgh / 2
	for gap > 0 {

		insertSortStep(nums, gap)
		// 缩小增量,直到 增量为1
		gap = gap / 2
	}
	return nums
}
// 插入排序(步长)
func insertSortStep(nums []int, step int) {
	for i := step; i < len(nums); i++ {
		// 比较 不同分组中 相同位置 的值
		for j := i; j < len(nums) && j >= step; j -= step {
			if nums[j] < nums[j-step] {
				swap(&nums[j], &nums[j-step])
			}
		}
	}
}

func swap(v1 *int, v2 *int) {
	*v1, *v2 = *v2, *v1

}

5.归并排序

不断一分为二拆分数组,当左右数组长度为1时,开始排序并合并,之后对合并后的数组(已排序)继续归并排序,采用分而治之的思想

func mergeSort(nums []int) []int {
   lgh := len(nums)
   // 注意:结束递归的条件 是lgh<2,如果是0,1则无法结束地柜,因为数组长度为1的数组会一直被分成数组长度为0,数组长度为1
   if lgh < 2 {
      return nums
   }
   left := lgh / 2
   return merge(mergeSort(nums[:left]), mergeSort(nums[left:]))
}

func merge(left []int, right []int) []int {
   var nums []int
   for (len(left) != 0) && (len(right) != 0) {
      if left[0] < right[0] {
         nums = append(nums, left[0])
         left = left[1:]
      } else {
         nums = append(nums, right[0])
         right = right[1:]
      }
   }

   if len(right) != 0 {
      nums = append(nums, right...)
   }

   if len(left) != 0 {
      nums = append(nums, left...)
   }
   return nums
}


func main() {
   test := []int{1, 23, 34, 3, 4, 5, 5, 6, 6, 77}
   result := mergeSort(test)
   fmt.Println(result)
}

6.堆排序

 func heapSort(nums []int) []int {

     lens := len(nums)
     buildHeap(nums,lens)
     for i:=lens-1;i>=0;i-- {
         swap(nums,0,i)
         lens -= 1
         heap(nums,0,lens)
     }

     return nums
 }

 func buildHeap(nums []int,lens int) {
     for i := lens/2;i>=0;i-- {
         heap(nums,i,lens)
     }
     fmt.Println(nums)
 }

 func heap(nums []int,i,lens int) {
     left := 2*i + 1
     right := 2*i + 2

     largest := i
     if left < lens && nums[left] > nums[largest] {
         largest = left
     }
     if right < lens && nums[right] > nums[largest] {
         largest = right
     }

     if largest != i {
         swap(nums,largest,i)
         heap(nums,largest,lens)
     }

 }


 func swap(arr []int,m,n int) []int {
     arr[m],arr[n] = arr[n],arr[m]
     return arr
 }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

算法相关-经典排序算法(goland实现) 的相关文章

  • MySQL数据库被攻击,被删库勒索,逼迫我使出洪荒之力进行恢复数据

    昨天连夜赶了一篇文章 讲述了一个被黑客连续攻击服务器三次的普通 搬砖人 一次比一次艰难 一次比一次狠 我给大家看几张图 看看黑客的 佳作 首先创建一个数据库 README FHX 然后创建表 README 插入一条数据 内容如下 内容 以下
  • 学生信息后台管理系统(GUI)

    一 目的 通过制作学生信息后台管理系统熟悉java中JDBC和CUI 图形用户接口 的使用 二 实验工具 1 Eclipse IDE Version 2020 12 4 18 0 2 mysql 3 Navicat Premium 15 数
  • string常见接口的使用(基于c++标准库中的STL)

    前言 string是c 中常见的容器 它是用来管理字符的 它在物理上是可以动态增长的线性表 对于了解它的使用 以及常见的接口使用对于我们日常开发和使用是很有必要的 所以接下来让我们一起来了解一下string常见的接口吧 目录 1 strin

随机推荐

  • 线程池用例

    线程池逻辑类 public class TaskExecutorService private final ExecutorService pool private final ThreadPoolExecutor pool private
  • HTML 5 标签、属性、事件及浏览器兼容性速查表

    HTML 5 可以说是近十年来 Web 标准最巨大的飞跃 和以前的版本不同 HTML 5 并非仅仅用来表示 Web 内容 它的使命是将 Web 带入一个成熟的应用平台 在这个平台上 视频 音频 图象 动画 以及同电脑的交互都被标准化 尽管
  • 相比引流,期货公司更应该借助私域提升留存和转化

    近期 我们和很多期货公司都有过交流和沟通 相较于如何提升产品留存和转化 大家似乎更关注如何引流 我理解大家对流量获取的焦虑 但回归运营的底层逻辑 产品的留存和转化其实更为重要 现如今很多期货公司已陆续借助企业微信搭建私域流量池 虽然了解了市
  • VFloss pytorch

    Loss functions import torch import torch nn as nn from utils general import bbox iou from utils torch utils import is pa
  • Unity3D之Rigidbody

    目录 常用的Rigidbody属性和方法 rigidbody AddForce rigidbody AddTorque rigidbody velocity rigidbody angularVelocity rigidbody Sleep
  • 国家语言对照表

    国家 地区 语言代码 国家 地区 语言代码 简体中文 中国 zh cn 繁体中文 台湾地区 zh tw 繁体中文 香港 zh hk 英语 香港 en hk 英语 美国 en us 英语 英国 en gb 英语 全球 en ww 英语 加拿大
  • Spring源码从入门到精通---@Scope&@Lazy(三)

    上篇文章主要介绍了 ComponentScan的注解 Spring源码从入门到精通 ComponentScan 二 这篇文章主要介绍单例模式 多例模式 懒加载 先上目录结构 这篇文章先创建了beanConfig2文件 1 多例模式 单例模式
  • Compile Options--编译选项

    目的 其主要作用是用于调试跟踪和测试 主要包含 MT TASK MT ZDO FUNC and other MT compile options LCD SUPPORTED LCD SUPPORTED DEBUG BLINK LEDS 且看
  • 【产量预测】BP和GRNN神经网络预测粮食产量【含Matlab源码 1247期】

    一 BP神经网络简介 1 BP神经网络概述 BP Back Propagation 神经网络是1986年由Rumelhart和McCelland为首的科研小组提出 参见他们发表在Nature上的论文 Learning representat
  • 第二章 常用安全工具

    目录 1 Kali系统工具分类 2 Kali Top10工具 1 Kali系统工具分类 信息收集 Information Gathering 主要目的是收集渗透测试目标的基本信息 包括操作系统信息 网络配置信息 应用服务信息等 脆弱性分析
  • Python:读取CSV文件的某几列

    三种读取方式如下 import csv import pandas as pd with open 2 csv r as csvfile reader csv reader csvfile column1 row 1 for row in
  • 【Docker应用篇】GitLab代码私服

    Docker应用篇 GitLab代码私服 什么是GitLab 概述 基于 Docker 安装 GitLab 访问 GitLab 的账户管理 创建用户 设置账户信息 修改用户密码 退出并使用新账户登录 GitLab GitHub 使用 SSH
  • 单例模式的八种写法比较

    单例模式是最常用到的设计模式之一 熟悉设计模式的朋友对单例模式都不会陌生 一般介绍单例模式的书籍都会提到 饿汉式 和 懒汉式 这两种实现方式 但是除了这两种方式 本文还会介绍其他几种实现单例的方式 让我们来一起看看吧 简介 单例模式是一种常
  • Java开发工具

    文章目录 一 Sublime Text 二 IDEA 一 Sublime Text 官网 Sublime Text 说明 文本编辑器 适合初学者练习手写代码 特点 支持多行编辑 二 IDEA
  • Windows powershell添加自定义快捷指令(Linux下对比)

    Windows Powershell 1 创建并修改Windows Powershell 启动执行文件 echo PROFILE 编辑C Users hongyang jia Documents PowerShell Microsoft P
  • QT编程----事件

    QT程序设计进阶 事件 Qt事件 Qt程序是事件驱动的 程序的每个动作都是由幕后某个事件所触发 Qt事件的类型很多 常见的qt的事件如下 键盘事件 按键按下和松开 鼠标事件 鼠标移动 鼠标按键的按下和松开 拖放事件 用鼠标进行拖放 滚轮事件
  • 基于振动传感器数据构建预测性维护AI模型

    预测性维修 Predictive Maintenance 简称PdM 是以状态为依据 Condition Based 的维修 在机器运行时 对它的主要 或需要 部位进行定期 或连续 的状态监测和故障诊断 判定装备所处的状态 预测装备状态未来
  • 1030 完美数列

    给定一个正整数数列 和正整数 p 设这个数列中的最大值是 M 最小值是 m 如果 M mp 则称这个数列是完美数列 现在给定参数 p 和一些正整数 请你从中选择尽可能多的数构成一个完美数列 输入格式 输入第一行给出两个正整数 N 和 p 其
  • 华为校招机试 - 单词重量(Java)

    题目描述 每个句子由多个单词组成 句子中的每个单词的长度都可能不一样 我们假设每个单词的长度Ni为该单词的重量 你需要做的就是给出整个句子的平均重量V 输入描述 无 输出描述 无 用例 输入 Who Love Solo 输出 3 67 说明
  • 算法相关-经典排序算法(goland实现)

    概述 插入排序 将未排序的元素同已排序的元素从后往前比较 带排序元素 a 被比较元素 b 如果a