位置: IT常识 - 正文

十大经典排序算法(下)(十大经典排序算法(动图演示C 实现))

编辑:rootadmin
十大经典排序算法(下)

推荐整理分享十大经典排序算法(下)(十大经典排序算法(动图演示C 实现)),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:十大经典排序算法,十大经典排序算法总结,十大经典排序算法菜鸟教程,十大经典排序算法菜鸟教程,十大经典排序算法java,十大经典排序算法总结,十大经典排序算法java,十大经典排序算法总结,内容如对您有帮助,希望把文章链接给更多的朋友!

🍓个人主页:bit.. 

🍒系列专栏:Linux(Ubuntu)入门必看   C语言刷题      数据结构与算法  HTML和CSS3

目录

1.6 快速排序

1. 算法步骤

2. 动图演示

3.代码实现

 1.7 堆排序

1. 算法步骤

2. 动图演示

3. 代码实现

1.8 计数排序

1. 计数排序的特征

2. 动图演示

3.代码实现

 1.9 桶排序

1. 什么时候最快

2. 什么时候最慢

3. 示意图

3.代码实现

 1.10 基数排序

1. 基数排序 vs 计数排序 vs 桶排序

2. LSD 基数排序动图演示

3.代码实现


1.6 快速排序

快速排序,一种排序很快的方法,使用分治思想,就是说快速排序是通过把数据分成几部分来处理的一种算法。快排本身和其使用的分治思想都很重要,也是面试可能出现的一大难点。

1. 算法步骤

从数列中挑出一个元素,称为 "基准"(pivot);

重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;

递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;

2. 动图演示

3.代码实现public class QuickSort implements IArraySort { @Override public int[] sort(int[] sourceArray) throws Exception { // 对 arr 进行拷贝,不改变参数内容 int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); return quickSort(arr, 0, arr.length - 1); } private int[] quickSort(int[] arr, int left, int right) { if (left < right) { int partitionIndex = partition(arr, left, right); quickSort(arr, left, partitionIndex - 1); quickSort(arr, partitionIndex + 1, right); } return arr; } private int partition(int[] arr, int left, int right) { // 设定基准值(pivot) int pivot = left; int index = pivot + 1; for (int i = index; i <= right; i++) { if (arr[i] < arr[pivot]) { swap(arr, i, index); index++; } } swap(arr, pivot, index - 1); return index - 1; } private void swap(int[] arr, int i, int j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; }} 1.7 堆排序

堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。堆排序可以说是一种利用堆的概念来排序的选择排序。分为两种方法:

大顶堆:每个节点的值都大于或等于其子节点的值,在堆排序算法中用于升序排列;小顶堆:每个节点的值都小于或等于其子节点的值,在堆排序算法中用于降序排列;1. 算法步骤

创建一个堆 H[0……n-1];

把堆首(最大值)和堆尾互换;

把堆的尺寸缩小 1,并调用 shift_down(0),目的是把新的数组顶端数据调整到相应位置;

十大经典排序算法(下)(十大经典排序算法(动图演示C 实现))

重复步骤 2,直到堆的尺寸为 1。

2. 动图演示

3. 代码实现public class HeapSort implements IArraySort { @Override public int[] sort(int[] sourceArray) throws Exception { // 对 arr 进行拷贝,不改变参数内容 int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); int len = arr.length; buildMaxHeap(arr, len); for (int i = len - 1; i > 0; i--) { swap(arr, 0, i); len--; heapify(arr, 0, len); } return arr; } private void buildMaxHeap(int[] arr, int len) { for (int i = (int) Math.floor(len / 2); i >= 0; i--) { heapify(arr, i, len); } } private void heapify(int[] arr, int i, int len) { int left = 2 * i + 1; int right = 2 * i + 2; int largest = i; if (left < len && arr[left] > arr[largest]) { largest = left; } if (right < len && arr[right] > arr[largest]) { largest = right; } if (largest != i) { swap(arr, i, largest); heapify(arr, largest, len); } } private void swap(int[] arr, int i, int j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; }}1.8 计数排序

计数排序的核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。

1. 计数排序的特征

当输入的元素是 n 个 0 到 k 之间的整数时,它的运行时间是 Θ(n + k)。计数排序不是比较排序,排序的速度快于任何比较排序算法。

由于用来计数的数组C的长度取决于待排序数组中数据的范围(等于待排序数组的最大值与最小值的差加上1),这使得计数排序对于数据范围很大的数组,需要大量时间和内存。例如:计数排序是用来排序0到100之间的数字的最好的算法,但是它不适合按字母顺序排序人名。但是,计数排序可以用在基数排序中的算法来排序数据范围很大的数组。

通俗地理解,例如有 10 个年龄不同的人,统计出有 8 个人的年龄比 A 小,那 A 的年龄就排在第 9 位,用这个方法可以得到其他每个人的位置,也就排好了序。当然,年龄有重复时需要特殊处理(保证稳定性),这就是为什么最后要反向填充目标数组,以及将每个数字的统计减去 1 的原因。

 算法的步骤如下:

(1)找出待排序的数组中最大和最小的元素(2)统计数组中每个值为i的元素出现的次数,存入数组C的第i项(3)对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加)(4)反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1 2. 动图演示

3.代码实现public class CountingSort implements IArraySort { @Override public int[] sort(int[] sourceArray) throws Exception { // 对 arr 进行拷贝,不改变参数内容 int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); int maxValue = getMaxValue(arr); return countingSort(arr, maxValue); } private int[] countingSort(int[] arr, int maxValue) { int bucketLen = maxValue + 1; int[] bucket = new int[bucketLen]; for (int value : arr) { bucket[value]++; } int sortedIndex = 0; for (int j = 0; j < bucketLen; j++) { while (bucket[j] > 0) { arr[sortedIndex++] = j; bucket[j]--; } } return arr; } private int getMaxValue(int[] arr) { int maxValue = arr[0]; for (int value : arr) { if (maxValue < value) { maxValue = value; } } return maxValue; }} 1.9 桶排序

桶排序是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。为了使桶排序更加高效,我们需要做到这两点:

在额外空间充足的情况下,尽量增大桶的数量使用的映射函数能够将输入的 N 个数据均匀的分配到 K 个桶中

同时,对于桶中元素的排序,选择何种比较排序算法对于性能的影响至关重要。

1. 什么时候最快

当输入的数据可以均匀的分配到每一个桶中。

2. 什么时候最慢

当输入的数据被分配到了同一个桶中。

3. 示意图

元素分布在桶中:

然后,元素在每个桶中排序:

3.代码实现public class BucketSort implements IArraySort { private static final InsertSort insertSort = new InsertSort(); @Override public int[] sort(int[] sourceArray) throws Exception { // 对 arr 进行拷贝,不改变参数内容 int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); return bucketSort(arr, 5); } private int[] bucketSort(int[] arr, int bucketSize) throws Exception { if (arr.length == 0) { return arr; } int minValue = arr[0]; int maxValue = arr[0]; for (int value : arr) { if (value < minValue) { minValue = value; } else if (value > maxValue) { maxValue = value; } } int bucketCount = (int) Math.floor((maxValue - minValue) / bucketSize) + 1; int[][] buckets = new int[bucketCount][0]; // 利用映射函数将数据分配到各个桶中 for (int i = 0; i < arr.length; i++) { int index = (int) Math.floor((arr[i] - minValue) / bucketSize); buckets[index] = arrAppend(buckets[index], arr[i]); } int arrIndex = 0; for (int[] bucket : buckets) { if (bucket.length <= 0) { continue; } // 对每个桶进行排序,这里使用了插入排序 bucket = insertSort.sort(bucket); for (int value : bucket) { arr[arrIndex++] = value; } } return arr; } /** * 自动扩容,并保存数据 * * @param arr * @param value */ private int[] arrAppend(int[] arr, int value) { arr = Arrays.copyOf(arr, arr.length + 1); arr[arr.length - 1] = value; return arr; }} 1.10 基数排序

基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数。

1. 基数排序 vs 计数排序 vs 桶排序

基数排序有两种方法:

这三种排序算法都利用了桶的概念,但对桶的使用方法上有明显差异:

基数排序:根据键值的每位数字来分配桶;计数排序:每个桶只存储单一键值;桶排序:每个桶存储一定范围的数值;2. LSD 基数排序动图演示

3.代码实现/** * 基数排序 * 考虑负数的情况还可以参考: https://code.i-harness.com/zh-CN/q/e98fa9 */public class RadixSort implements IArraySort { @Override public int[] sort(int[] sourceArray) throws Exception { // 对 arr 进行拷贝,不改变参数内容 int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); int maxDigit = getMaxDigit(arr); return radixSort(arr, maxDigit); } /** * 获取最高位数 */ private int getMaxDigit(int[] arr) { int maxValue = getMaxValue(arr); return getNumLenght(maxValue); } private int getMaxValue(int[] arr) { int maxValue = arr[0]; for (int value : arr) { if (maxValue < value) { maxValue = value; } } return maxValue; } protected int getNumLenght(long num) { if (num == 0) { return 1; } int lenght = 0; for (long temp = num; temp != 0; temp /= 10) { lenght++; } return lenght; } private int[] radixSort(int[] arr, int maxDigit) { int mod = 10; int dev = 1; for (int i = 0; i < maxDigit; i++, dev *= 10, mod *= 10) { // 考虑负数的情况,这里扩展一倍队列数,其中 [0-9]对应负数,[10-19]对应正数 (bucket + 10) int[][] counter = new int[mod * 2][0]; for (int j = 0; j < arr.length; j++) { int bucket = ((arr[j] % mod) / dev) + mod; counter[bucket] = arrayAppend(counter[bucket], arr[j]); } int pos = 0; for (int[] bucket : counter) { for (int value : bucket) { arr[pos++] = value; } } } return arr; } /** * 自动扩容,并保存数据 * * @param arr * @param value */ private int[] arrayAppend(int[] arr, int value) { arr = Arrays.copyOf(arr, arr.length + 1); arr[arr.length - 1] = value; return arr; }}
本文链接地址:https://www.jiuchutong.com/zhishi/299399.html 转载请保留说明!

上一篇:2021年Windows下安装GPU版本的Tensorflow和Pytorch(windows2022下载)

下一篇:2022 uniapp基础掌握及面试题整理(uniapp零基础小白到项目实战)

  • 荣耀play4pro闪存规格有多大(荣耀play 4t pro存储规格)

    荣耀play4pro闪存规格有多大(荣耀play 4t pro存储规格)

  • vivox50和x50pro的区别(vivox50与x50pro的区别)

    vivox50和x50pro的区别(vivox50与x50pro的区别)

  • vivo手机怎么导出联系人(vivo手机怎么导入新手机)

    vivo手机怎么导出联系人(vivo手机怎么导入新手机)

  • 计算机网络协议三要素(计算机网络协议是什么意思)

    计算机网络协议三要素(计算机网络协议是什么意思)

  • iphone11双卡双待吗(iphone11双卡双待怎么切换)

    iphone11双卡双待吗(iphone11双卡双待怎么切换)

  • 抖音判定搬运的依据是什么(抖音判定搬运的是真的吗)

    抖音判定搬运的依据是什么(抖音判定搬运的是真的吗)

  • 路由器网关地址是多少(路由器网关地址和ip地址可以一样吗)

    路由器网关地址是多少(路由器网关地址和ip地址可以一样吗)

  • 荣耀9x有多长(华为荣耀9x手机有多长)

    荣耀9x有多长(华为荣耀9x手机有多长)

  • 苹果微信语音只能听到前几秒(苹果微信语音只能听到开头一秒)

    苹果微信语音只能听到前几秒(苹果微信语音只能听到开头一秒)

  • 为什么qq有消息不响(为什么QQ有消息不弹出来)

    为什么qq有消息不响(为什么QQ有消息不弹出来)

  • qq手机怎么分享屏幕(qq手机怎么分享聊天记录)

    qq手机怎么分享屏幕(qq手机怎么分享聊天记录)

  • 苹果手机收音孔在哪里(苹果手机收音孔坏了)

    苹果手机收音孔在哪里(苹果手机收音孔坏了)

  • 为什么apple id验证失败(为什么苹果验证id)

    为什么apple id验证失败(为什么苹果验证id)

  • excel表格怎么双面打印(excel表格怎么双击复制)

    excel表格怎么双面打印(excel表格怎么双击复制)

  • vivo手机怎么设置sos(vivo手机怎么设置桌面时间日期)

    vivo手机怎么设置sos(vivo手机怎么设置桌面时间日期)

  • 安卓手机如何打开 exe文件(安卓手机如何打开.bin文件)

    安卓手机如何打开 exe文件(安卓手机如何打开.bin文件)

  • 剪映怎么删除多余的部分(剪映怎么删除多余音轨)

    剪映怎么删除多余的部分(剪映怎么删除多余音轨)

  • 微信文字折叠怎么办(微信 文字 折叠)

    微信文字折叠怎么办(微信 文字 折叠)

  • wpsword怎么画直线(wps画直线怎么画直线)

    wpsword怎么画直线(wps画直线怎么画直线)

  • 全民k歌怎么合唱邀请(全民k歌怎么合唱邀请好友一起唱)

    全民k歌怎么合唱邀请(全民k歌怎么合唱邀请好友一起唱)

  • 华为运动健康怎么使用(华为运动健康怎么关闭锁屏显示)

    华为运动健康怎么使用(华为运动健康怎么关闭锁屏显示)

  • vivo手机hd怎么关闭(vivo手机hd怎么关掉)

    vivo手机hd怎么关闭(vivo手机hd怎么关掉)

  • 华为p30pro卡槽在哪里(华为p30pro卡槽在哪)

    华为p30pro卡槽在哪里(华为p30pro卡槽在哪)

  • 华为手机放大镜怎么开(华为手机放大镜怎么取消设置功能)

    华为手机放大镜怎么开(华为手机放大镜怎么取消设置功能)

  • cad布局怎样转模型(cad布局怎么转模型快捷键)

    cad布局怎样转模型(cad布局怎么转模型快捷键)

  • 开了移动数据没有网络(开了移动数据没有网络vivo)

    开了移动数据没有网络(开了移动数据没有网络vivo)

  • 苹果 Mac双系统如何切换?用Option键切换双系统的步骤分享(苹果mac双系统按住哪个键)

    苹果 Mac双系统如何切换?用Option键切换双系统的步骤分享(苹果mac双系统按住哪个键)

  • 办税员可以购票吗?
  • 实收资本库存现金凭证怎么开
  • 人工费用的核算例题
  • 已认证红字信息表
  • 在建工程转入固定资产当月计提折旧吗
  • 税金及附加包括个人所得税吗
  • 车贷抵押金计入会计科目?
  • 印花税缴款了发现报错了怎么办?
  • 将承兑汇票背书怎么操作
  • 印花税按次申报和按期申报区别
  • 公司购买6个月的保险
  • 房屋租赁发票在哪开
  • 个人所得税计算器2023
  • 小规模纳税人自开专票
  • 包销和代销哪个风险大
  • 会展服务服务费怎么是免税
  • 出售已计提减值准备的固定资产
  • 应交税费已交税金借方有余额
  • m1 mac 恢复出厂
  • 为什么盈余公积补亏不会影响留存收益
  • 税控盘技术服务费可以抵税吗
  • 跨年的收入可以在次年冲吗
  • 爱沙尼亚的故事
  • deepin声音
  • 公司收入算认缴出资吗
  • 普通发票主营业务收入销项负数发票怎么做账
  • msmpeng.exe 是什么
  • PHP:pcntl_sigtimedwait()的用法_PCNTL函数
  • 销售多余材料的收入会计分录
  • php访问mysql的五个基本步骤
  • 伦索伊斯马拉赫塞斯国家公园
  • 拱门国家公园景点
  • 在一株植物上行走的作文
  • 购买货物收到发票财务报表怎么提现
  • c#开发入门及项目实战
  • 广告模板网站
  • 增值税纳税申报表在哪里查询
  • 软件开发增值税即征即退政策
  • 发现以前年度损益调整怎么记账
  • 产品维修费的会计怎么做
  • dedecms插件
  • 事务所的账务处理
  • 个税系统中的离职怎么填
  • 利润表中本期金额是什么意思
  • sql2008降级2005
  • 公司销售红酒需要什么资质
  • 行政事业单位核销固定资产的账务处理
  • 后续加工环节的成本利润
  • 哪里还有备用金可以借
  • 结算账户分为哪几种?其用途结构如何?
  • 什么是增资扩股协议
  • 市盈率为负数是说明什么呢
  • 收不回来的其他应收账款如何处理?
  • mysql缩印
  • mysql事务命令
  • mysql复制命令
  • windows预览版计划
  • 定时清理注册表会怎么样
  • 取消windows开机登录密码
  • 教程图解
  • ims文件是什么意思
  • winxp和win7双系统
  • 360tray占用大量内存
  • windows8鼠标没反应怎么办
  • linux的vi使用教程
  • 在Linux系统中安装Anaconda
  • linux怎么使用
  • win7系统玩游戏怎么样
  • win10系统怎么cmd
  • Cocos2d-x之getVisibleSize,getContentSize,boundingBox,getContentSizeInPixels,convertToGL,convertToUI
  • css设置表格隔行换色
  • Unity3D游戏开发引擎
  • shell 比较大小
  • 简述jquery的优势
  • easyui框架的优缺点
  • 关于房地产企业所得税涉税处理表述正确的有
  • 无偿划转暂行规定
  • 朝阳区地方税务局官网
  • 四川成都离剑门多远
  • 舆论与舆情之间的关系是怎样的?
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设