排序算法总结(五)——非比较排序

常见的排序算法汇总(详解篇) 所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。稳定性 :假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中, r[i]=r[j] ,且 r[i] 在 r[j] 之前,而在排序后的序列中, r[i] 仍在 r[j] 之前,则称这种排序算法是稳定的;否则称为不稳定的。数据元素全部放在内存中的排序。数据元素太多不能同时放在内存中,根据排序过程的要求不能在内外存之间移动数据的排序。 阅读详情

1.基数排序
这里的基数指的是位数:例如对十进制来说,指的是个位、十位、百位。

基本思想:
(1)首先设置号码为0-9的十个篮子;
(2)第一轮将序列的数字按照个位依次放置到对应号码的篮子中,并形成新的排序;
(3)第二轮在第一轮排序的基础上,按照十位依次放置到对应号码的篮子中,同样形成新的排序;
(4)依次类推,直到没有更好的位数,此时的排序即为最终的排序。
注意在放入篮子中的,不能改变元素本身相互之间的顺序,先遍历到的数字要先放进去。

具体示意图如下所示:
(图片来自https://www.cnblogs.com/ECJTUACM-873284962/p/6935506.html,侵权删)

第一轮排序后:
这里写图片描述
第二轮排序后:
这里写图片描述

代码实现:

public class JishuSort {

    public static void main(String[] args) {
        int[] a = {12,33,41,14,6,14};
        sort(a);

        for(int i = 0;i<a.length;i++)
            System.out.println(a[i]);
    }

    public static void sort(int[] a){
        int len = a.length;
        int max = a[0];
        //选出最大值,根据最大值得到最高位,计算循环次数
        for(int i=1;i<len;i++){
            if(a[i]>max){
                max = a[i];
            }
        }
        //定义二维数组记录排序存放排序数据,即十个篮子
        int[][] buckets = new int[10][len];
        //记录buckets中每个组里存放的数据个数,即每个篮子中放入的数据个数
        int[] num = new int[10];
        //使用1、10、100、1000等来记录位数
        int h = 1;

        while(h<max){

            //依次将数据放置到对应编号的篮子中
            for(int i = 0;i<len;i++){
                buckets[(a[i]/h)%10][num[(a[i]/h)%10]] = a[i];
                num[(a[i]/h)%10]++;
            }

            //将每轮排序后的结果返回到a
            int n = 0;
            for(int i = 0;i<10;i++){
                if(num[i]!=0){
                    for(int j = 0;j<num[i];j++){
                        a[n] = buckets[i][j];
                        n++;
                    }
                }
            //注意每轮排序后需要将num置为0,即将篮子清空
            num[i] = 0;
            }
            //增加位数
            h*=10;
        }
    }
}

2.桶排序
基本思想:根据数据的范围将其分配到不同的桶中,桶中的元素各自排序,最后合并到一起。

算法步骤:
(1)初始化建立一定数量的buckets;
(2)遍历原始序列,根据元素大小放置到对应的bucket中;
(3)对非空的buckets中的元素进行排序;
(4)按照顺序返回buckets中的元素到原始数组中即可完成排序。

可参看如下例子:
(图片来自https://img-blog.youkuaiyun.com/20150929092136858,侵权删)
这里写图片描述

代码实现:
参考:https://www.cnblogs.com/zer0Black/p/6169858.html

import java.util.ArrayList;
import java.util.Collections;

public class BucketSort {

    public static void main(String[] args) {
        int[] a = {12,33,41,14,6,14};
        sort(a);

        for(int i = 0;i<a.length;i++)
            System.out.println(a[i]);
    }

    public static void sort(int[] a){
        int max = a[0];
        int min = a[0];
        int len = a.length;

        //根据序列中的最大值和最小值确定bucket的数量
        for(int i = 1;i<len;i++){
            if(a[i] > max)
                max = a[i];
            if(a[i] < min)
                min = a[i];
        }

        //bucket的数量blen
        int blen = (max-min)/len + 1;

        //初始化bucket
        ArrayList<ArrayList<Integer>> buckets = new ArrayList<ArrayList<Integer>>(blen);
        for(int i = 0;i<blen;i++){
            buckets.add(new ArrayList<Integer>());
        }
        //在每个bucket中存放元素
        for(int i = 0;i<len;i++){
            buckets.get((a[i]-min)/len).add(a[i]);
        }

        //对bucket内元素进行排序
        for(int i=0;i<blen;i++){
            Collections.sort(buckets.get(i));
        }

         System.out.println(buckets.toString());
    }
}

3.计数排序
基本思想:对每一个元素x,确定小于x的元素个数。因此我们就可以直接把x放到最终输出数组中的相应位置上。

算法步骤:
(1)设置辅助数组count,长度为max-min+1;
(2)遍历无序序列,将元素依次放置到count数组对应序号的位置上,得到每个元素出现的次数,例如a[i]出现了3次,则count [a[i] - min] = 3;
(3)遍历count数组,使得count[i] = count[i]+count[i-1],由此得到小于i的元素的个数,即i在整个无序序列中应该拍在第count[i]位;
(4)建立临时数组temp,遍历无序序列,如a[i],根据count得到小于a[i]的个数,将a[i]直接放置到temp对应位置上。

代码实现:

public class CountSort {
    public static void main(String[] args) {
        int[] a = {12,33,41,14,6,14};
        int[] re = sort(a);

        for(int i = 0;i<re.length;i++)
            System.out.println(re[i]);
    }

    public static int[] sort(int[] a){
        int max = a[0];
        int min = a[0];
        int len = a.length;

        //计算序列最大值和最下值,确定count数组的长度为max-min+1
        for(int i = 1;i<len;i++){
            if(a[i]>max)
                max = a[i];
            if(a[i]<min)
                min = a[i];
        }

        int[] count = new int[max-min+1];
        int[] temp = new int[len];//临时数组

        //计算每个元素出现的次数
        for(int i=0;i<len;i++){
            count[a[i]-min]++;
        }

        //计算小于某元素的元素的个数
        for(int i=1;i<max-min+1;i++){
            count[i] = count[i] + count[i-1];
        }
        //将元素放置到temp对应位置中,并且记得每放置一个元素,对应的count--;
        for(int i = 0;i<len;i++){
             if(count[a[i]-min]!=0){
                 temp[count[a[i]-min]-1] = a[i];
                 count[a[i]-min]--;
             }  
        }
        return temp;
    }
}
告别QXDM:在Android Studio中调试与验证高通NV读写功能的完整流程 本文详细介绍了在Android Studio中调试与验证高通NV分区读写功能的完整流程,替代传统的QXDM工具。通过JNI接口层、HAL服务层和Diag通信层的架构设计,开发者可以在熟悉的IDE环境中高效完成NV操作,包括环境配置、错误处理和性能优化等关键实践。 阅读详情

相关推荐

手把手教你用 Docker 构建自己的 CentOS 基础镜像

目录一、准备CentOS基础镜像二、撰写Dockerfile三、构建Docker镜像四、生成Docker容器 相信码农们经常会听说:虚拟机将成为历史,Docker才是未来 !!! 事实如此,现在大部分公司都在用 Docker 技术,想拥有自己的 Docker 专属镜像,那么 Dockerfile 就是入门,现在让我们一起来看一下 ------ 构建 Docker 镜像的全过程。 好文章 记得收藏...

Nick.Peng's Blogs 1万+

十大常用经典排序算法总结!!!

爆肝整理!堪称全网最详细的十大常用经典排序算法总结!!! 写在开头,本文经过参考多方资料整理而成,全部参考目录会附在文章末尾。很多略有争议性的细节都是在不断查阅相关资料后总结的,具有一定普适性。 总表: 相关解释: 稳定:如果原本序列中a在b前面且a=b,排序后a仍在b前面,顺序不变; 不稳定:如果原本序列中a在b前面且a=b,排序后a可能在b后面,顺序可能发生改变; 内排序:所有排序操作均在内存中完成; 外排序:由于数据量太大,将其放入磁盘中,排序过程中需要磁盘与内存之间的数据传输;

Jing Sir的博客 5万+

ADS交叉耦合振荡器VCO相位噪声优化仿真实践

本文详细介绍了在ADS软件中搭建和优化交叉耦合VCO相位噪声的完整仿真实践。通过谐波平衡与瞬态仿真分析电路性能,并重点阐述了通过提升谐振腔Q值、优化晶体管工作点及改善尾电流源来有效降低相位噪声的具体方法,为射频电路设计提供了实用指南。

weixin_29235923的博客 631

七大经典排序算法总结【详解】

数据量规模较小,考虑插入或选择。当元素分布有序时插入将大大减少比较和移动记录的次数,如果不要求稳定性,可以使用选择,效率略高于插入;数据量规模中等,使用希尔排序;数据量规模较大,考虑堆排序(元素分布接近正序或逆序)、快速排序(元素分布随机)和归并排序(稳定性);一般来说不使用冒泡。

weixin_63189874的博客 8696

HIL(硬件在环)技术汇总梳理

HIL(Hardware-in-the-Loop)测试领域的知名公司有dSPACE、NI、Vector和speedgoat等,本文是针对这几家HIL技术的对比分析。

Mr.Cssust的博客 3686

Android Termux 安装Kali Linux 或 kali Nethunter史诗级详细教程

Termux 安装kali

风云小虾米的博客 6万+

排序算法(五) 三种非比较排序

计数排序 思路 很简单,就是设一个哈希表来统计数组各元素的个数,统计完毕后计算前缀和,将各元素统计数转化为应该放的下标位置,最后遍历原数组各元素,将元素放到哈希表映射的位置即可。(注意每次放一个元素对应下标位置计数减1) 实现 class Solution { public: // 数据范围 -50000 <= A[i] <= 50000, 故数组要容纳100000个数 int SIZE = 100001; // 设置偏移量的目的是使得所有值都为正值,防止数组溢出

Tracker647的博客 1378

【Excel VBA 编程】批量核对两张表格数据,行和列显示顺序均被打乱

利用数据字典在 Excel 中进行表格数据的核对,该表格含有多行多列,并且行和列顺序是打乱的,批量核对数据后将差异输出

wei1019的专栏 1291

【十八】常见十种排序算法总结笔记

https://www.cnblogs.com/onepixel/articles/7674659.html 一、排序算法简介 1.1分类 排序算法分为 1.比较类排序 插入排序 选择排序 交换排序 归并排序 2.非比较类排序 基数排序 1.2 算法复杂度 稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面。 不稳定:如果a原本在b的前面,而a=b,排序之后...

Sid小杰的博客 2927

CSP-J 复试考点

可以用来训练思维,对于学习时间短的同学,动态规划可以帮助你迅速进入编程状态,也有助于帮你发现题目背后可能隐藏的更简便的算法。动态规划、贪心都是和子问题相关的,动态规划的基本思想是将一个大的问题划分成子问题,接着分别求解,而且能够将一些重复的计算记忆化,大大提高效率。难度加大,会涉及到二分、动态规划之类的算法,容易遗漏考虑点,不易得全分,考试的时候要注意全面性。一般是压轴题,算法不明显,剪枝的搜索、动态规划、状压 DP、树形 DP 、树、图等。枚举算法是指,列举出所有可能的取值,从中找出最优解。

GuanHeTian的博客 2214

Python-OpenCV及cv2,numpy库最新安装教程[最全步骤]

安装教程目录前言OpenCV-Python安装教程报错解决cv2安装numpy安装opencv安装(附加)总结 前言 首先,我知道一些看到我的Blog的人已经在网上找了很多歪路子,现在已经火冒三丈了(我也是这样过来的hhhh),那么现在,深呼吸,跟着我的教程,不要着急,每一步都要读一遍。完整安装过程需要1个小时左右(仅供参考,本人第一次安装python花了一天(确信)) OpenCV-Python...

qq_45425286的博客 7430

排序算法五------其他排序方式(非比较排序)

一、计数排序-----鸽巢原理1、找范围2、给出辅助空间(空间中记录每条数据出现的次数)3、整体遍历一遍数据,统计每一个数据出现的次数4、回收数据(回收到原空间):根据下标,给出存储在该下标下的数据假设范围为M到n,则:时间复杂度:O(3n)即O(n)空间复杂度:借助了一个辅助空间O(n)场景:数据密集的集中在某一个范围内实现代码://一个数密集的集中在哪个范围,但是没有给定范围 void Cou...

xuruhua的博客 714

示波器核心参数选型指南:带宽、采样率与嵌入式调试实战

示波器是电子工程师进行信号观测与故障诊断的基础仪器,其性能由带宽、采样率、通道数、存储深度、触发系统和探头特性共同决定。带宽定义高频响应边界,需遵循5倍法则以保障数字信号上升沿测量精度;采样率则依据奈奎斯特定理并结合工程冗余(通常≥2.5×带宽)实现可靠时域重建。二者协同影响信号完整性评估能力,尤其在UART、I²C、SPI等嵌入式总线调试中至关重要。高存储深度支持长时捕获与毛刺定位,智能触发与硬件协议解码进一步将波形分析升维至语义级。本文围绕真实嵌入式场景,解析参数间的耦合关系与典型误用陷阱。

weixin_42588877的博客 91

史上最全经典排序算法总结(Java实现)

查找和排序算法是算法的入门知识,其经典思想可以用于很多算法当中。因为其实现代码较短,应用较常见。所以在面试中经常会问到排序算法及其相关的问题。但万变不离其宗,只要熟悉了思想,灵活运用也不是难事。一般在面试中最常考的是快速排序和归并排序,并且经常有面试官要求现场写出这两种排序的代码。对这两种排序的代码一定要信手拈来才行。还有插入排序、冒泡排序、堆排序、基数排序、桶排序等。面试官对于这些排序可能会要求...

ThinkWon的博客 2万+

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

排序算法之非比较排序(基数排序和计数排序)

计数排序和基数排序

m0_64770095的博客 1329

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

十大经典排序算法总结(Java实现+动画)

最近在梳理《数据结构与算法》的内容,在网上看了几篇不错的文章,现在根据自己的理解重新整理一下十大经典排序算法。实际生产中,最好的算法一定是结合数据集本身的特点(大小,长度,是否已经基本有序等等)来选择的,不要拘泥于算法本身。 我参考的文章有:https://www.cnblogs.com/guoyaohua/p/8600214.html,https://blog.youkuaiyun.com/liang_g...

meibenxiang的博客 5万+

排序(五)——非比较排序+排序总结

我们前面学了几种比较排序,这里我们对他们进行一个总结时间复杂度直接插入排序:O(N^2)希尔排序: O(N^1.3)选择排序: O(N^2)堆排序: O(NlogN)冒泡排序: O(N^2)快排: 最好O(NlogN),最坏O(N^2),但是三数取中优化之后一般不会出现最坏归并排序: O(NlogN)空间复杂度直接插入排序:O(1)希尔排序: O(1)选择排序: O(1)

weixin_64099089的博客 1235

【排序算法】Java实现三大非比较排序:计数排序、桶排序、基数排序

本章中详解了数据结构中的三大非计较排序,分析了其原理和优缺点以及效率,最后用Java代码实现出来。

yican2580的博客 1808

数据结构初阶(17)排序算法——非比较排序(计数排序·动图演示)、排序算法总结

排序算法——非比较排序、排序算法总结

2301_79907403的博客 855

【数据结构】十大经典排序算法总结与分析

十大经典排序算法总结与分析,以及一些排序中相关内容的补充

2301_80191662的博客 2760

非比较排序

计数排序、基数排序、桶排序 非比较排序算法,平均时间复杂度都是O(N). 这些排序元素,因为其关键值本身就含有了定位特征,因而不需要比较就可以确定其前后位置。 1、计数排序是一种简单的排序方法,将排序结果放到另一个的新的数组中。       计数排序要求 待排序的元素的关键值是位于0-k之间的正整数。因而是个非常特殊的情况。       输入数组A:元素关键值是 0-K的正整数,可以有重复

wangkechuang的专栏 2512

排序算法——计数排序(非比较排序)

​ 哈喽大家好,我是保护小周ღ,本期为大家带来的是排序算法中的计数排序,非常的有意思,值得学习而且计数排序是非交换排序,分享所有源代码,粘贴即可运行,保姆级讲述,包您一看就会,快来试试吧~ ​...

保护小周ღ的博客 3268

排序算法——非比较排序

本文给出了非比较排序:计数排序、桶排序和基数排序的基本思想和java实现

qq_45241885的博客 507

计数排序与桶排序:非比较排序的魔法

计数排序和桶排序是两种高效的非比较排序算法。计数排序通过统计元素出现次数直接确定位置,适合整数且范围小的数据集,时间复杂度为O(n+k)。桶排序采用分治策略,将数据分配到多个桶中分别排序后合并,适合均匀分布的数据,最佳情况可达O(n)。计数排序实现简单但受限数据范围,桶排序更灵活但对数据分布敏感。两者都比传统比较排序(O(nlogn))在某些场景下更高效,但各有适用条件和局限性。

从不水文,坚持创作,加油 1104

深入理解常见排序算法:从原理到实践

排序是将一组记录按照某个或某些关键字的大小,以递增或递减的顺序重新排列的过程。购物筛选:按价格从低到高排序商品。院校排名:按总分从高到低排列高校。排序算法的选择需综合考虑数据规模、数据特征和应用场景。本文详细讲解了常见排序算法的原理、实现及优化方法,并通过代码示例和性能对比帮助读者深入理解。掌握这些知识后,可以灵活选择适合的算法解决实际问题。

2503_90358233的博客 2075

各种排序算法总结和比较

排序算法可以说是一项基本功,解决实际问题中经常遇到,针对实际数据的特点选择合适的排序算法可以使程序获得更高的效率,有时候排序的稳定性还是实际问题中必须考虑的,这篇博客对常见的排序算法进行整理,包括:插入排序、选择排序、冒泡排序、快速排序、堆排序、归并排序、希尔排序、二叉树排序、计数排序、桶排序、基数排序。 代码都经过了CodeBlocks的调试,但是很可...

3726

数据结构与算法之非比较排序【Java】

比较排序与非比较排序的对比   常见的快速排序、归并排序、堆排序、冒泡排序等属于比较排序。在排序的最终结果里,元素之间的次序依赖于它们之间的比较。每个数都必须和其他数进行比较,才能确定自己的位置。在冒泡排序之类的排序中,问题规模为n,又因为需要比较n次,所以平均时间复杂度为O(n²)。在归并排序、快速排序之类的排序中,问题规模通过分治法消减为logN次,所以时间复杂度平均O(nlo...

195
上一篇: 排序算法总结(四)——归并排序排序
下一篇: LeetCode 之 3sum
小菜鸟要高飞
博客等级 码龄12年 14粉丝 77原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值