基数排序

基数排序(桶排序)整理

好久不见. 提交于 2019-12-31 02:26:33
基数排序介绍 1.基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是通过键值的各个位的值,将要排序的元素分配至某些“桶”中,达到排序的作用 2.基数排序法是属于稳定性的排序,基数排序法的是效率高的稳定性排序法 3.基数排序(Radix Sort)是桶排序的扩展 4.基数排序是1887年赫尔曼·何乐礼发明的。它是这样实现的:将整数按位数切割成不同的数字,然后按每个位数分别比较。 基数排序的基本思想 1.将所有待比较数值统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。 2.这样说明,比较难理解,下面我们看一个图文解释,理解基数排序的步骤 图解 说明 1.基数排序是对传统桶排序的扩展,速度很快。 2.基数排序是经典的空间换时间的方式,占用内存很大, 当对海量数据排序时,容易造成 OutOfMemoryError 。 3.基数排序时稳定的。[注:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的

动画 | 什么是基数排序?

风格不统一 提交于 2019-12-24 08:34:51
基数排序和计数排序一样无需进行比较和交换,和桶排序一样利用分布和收集两种基本操作进行排序。基数排序是把每一个元素拆成多个关键字,一个关键字可以在每一个元素上同等的位置进行计数排序,一个元素拆成多个关键字可以看作是要进行几轮分桶,以一个元素最长的长度为准。 基数排序可以看成多(单)关键字的排序,可以想象成桶排序那样分桶排序,也可以像计数排序那样归约化分治。 基数排序的思想是将待排序序列中的每组关键字进行桶排序。例如整数序列[103, 9, 1,7,11,15, 25, 201, 209, 107, 5]上每个位、十位和百位上的数字看成是一个关键字。 基数排序有两种方式进行,一种是LSD,从右边关键字开始排序,另一种是MSD,从左边关键字开始排序。 基数排序LSD 我们将输入数组[103, 9, 1,7,11,15, 25, 201, 209, 107, 5],从右边关键字开始,以个位数上开始分桶,对于数字,每一个关键字取值范围是0~9,最多需要10个桶。如果是字符,按ASCII码最多需要128个桶,看情况而定。 为了保证元素之间的稳定性,就按计数排序一样,将给出一个统计数组c,长度为10,统计输入数组每一个元素对应的关键字。然后从统计数组c第2个位置开始,进行当前一项和前一项的累加。累加完之后反向填充数组b,也将数组b直接复制到数组array。 再进行循环操作exp *= 10

数据结构与算法基础--第14周01--第8章排序1--8.1排序概述

百般思念 提交于 2019-12-23 01:09:06
>排序:什么是排序? 将一组杂乱无章的数据按照一定规律顺次排列起来,即: 将无序序列排成一个有序序列(由小到大/由大到小)的运算。 >>排序方法的分类: 1、按数据 存储介质 :内部排序和外部排序 2、按 比较器个数 :串行排序和并行排序 3、按 主要操作 :比较排序和基数排序 4、按 辅助空间 :原地排序和非原地排序 5、按 稳定性 :稳定排序和非稳定排序 6、按 自然性 :自然排序和非自然排序 >>按照排序依据的原则: 插入排序 :直接插入排序、折半插入排序、希尔排序 交换排序 :冒泡排序、快速排序 选择排序 :简单选择排序、堆排序 归并排序 :2-路归并排序 基数排序 >>按照排序所需工作量: 简单排序方法 :T(n)=O(n²) 基数排序 :T(n)=O(d.n) 先进的排序方法 :T(n)=O(nlogn) 来源: CSDN 作者: sinat_38792591 链接: https://blog.csdn.net/sinat_38792591/article/details/103654625

python算法

南楼画角 提交于 2019-12-20 23:46:22
排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。常见的内部排序算法有:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。用一张图概括 关于时间复杂度: 平方阶 (O(n2)) 排序 各类简单排序:直接插入、直接选择和冒泡排序。 线性对数阶 (O(nlog2n)) 排序 快速排序、堆排序和归并排序。 O(n1+§)) 排序,§ 是介于 0 和 1 之间的常数。 希尔排序。 线性阶 (O(n)) 排序 基数排序,此外还有桶、箱排序。 关于稳定性: 稳定的排序算法:冒泡排序、插入排序、归并排序和基数排序。 不是稳定的排序算法:选择排序、快速排序、希尔排序、堆排序。 名词解释: n:数据规模 k:“桶”的个数 In-place:占用常数内存,不占用额外内存 Out-place:占用额外内存 稳定性:排序后 2 个相等键值的顺序和排序之前它们的顺序相同 冒泡排序 冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。

数据结构和算法排序之基数排序

痴心易碎 提交于 2019-12-20 15:01:14
基数排序: 基本思想: 将所有待比较数值统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。 package Sort ; import java . util . Arrays ; //基数排序,这段代码只适用于元素都为整数的数组排序,若有负数会出现数组越界异常,我在不含有负数数组的基数排序代码上进行了改进,因此这段代码也适用于含有负数的数组进行基数排序 /* * 如要实现含有负数的基数排序 * 基本思想: * 1.将原始数组分割为两个模块,一个模块都是负数,一个模块都是正数。将负数模块全部转为正数,两个模块分别进行基数排序 *2.将基数排序后的负数数组(之前先进行了转正),转为负数,然后使用Arrays.sort()按顺序排列; * 3.两个数组进行合并 * */ public class RadixSort { public static void main ( String [ ] args ) { int [ ] arr = { - 53 , 3 , 542 , 748 , 14 , - 214 } ; //如果数组中含有负数,那么就分割,正数放在一个数组,负数放在一个数组 //1.提取负数 int count = 0 ; //记录负数个数 for ( int i = 0 ;

线性排序:如何根据年龄给100W用户数据排序

三世轮回 提交于 2019-12-16 09:21:16
线性排序:如何根据年龄给100W用户数据排序 桶排序、计数排序、基数排序,因为这些算法的时间复杂度是线性的,所以叫做线性排序,之所以能做到线性的时间复杂度,是因为这三个算法是基于比较的排序算法,都不涉及元素之间的比较操作 重点是掌握这些排序算法的适用场景 桶排序(bucket sort) 核心思想是将要排序的数据分到几个有序的桶里,每个桶里的数据再单独进行排序,桶内排完序之后,再把每个桶里面的数据按照顺序依次取出,组成的序列就是有序的 桶排序的时间复杂度是O(n):如果要排序的数据有n个,把它们均匀的划分到m个桶内,每个桶里就有k = n/m个元素,每个桶内部使用快排,时间复杂度为O( k ∗ l o g k k*logk k ∗ l o g k ),m个桶就是O( m ∗ k ∗ l o g k m*k*logk m ∗ k ∗ l o g k ),因为k=n/m,所以m个桶即整个桶的时间复杂度是O( n ∗ l o g ( n / m ) n*log(n/m) n ∗ l o g ( n / m ) ),当桶的个数m接近数据个数n时,log(n/m)就是一个非常小的常量,桶排序的时间复杂度接近O(n) 桶排序看起来很优秀,但是不能替代之前的排序算法,因为桶排序对排序数据的要求很苛刻,首先,要排序的数据需要很容易划分成m个桶,并且,桶与桶之间有天然的大小顺序

基数排序的实现

≡放荡痞女 提交于 2019-12-14 11:11:14
import java . util . Arrays ; public class RadixSort { public static void main ( String [ ] args ) { int [ ] array = new int [ 8 ] ; int len = array . length ; for ( int i = 0 ; i < len ; i ++ ) { array [ i ] = ( int ) ( Math . random ( ) * 100 ) ; } System . out . println ( "待排序的数据为:" + Arrays . toString ( array ) ) ; radixSort ( array ) ; System . out . println ( "排序过后的数据为:" + Arrays . toString ( array ) ) ; } /* 按照位数把数放到相应的桶里面,直到排序完成~ */ public static void radixSort ( int [ ] array ) { int max = array [ 0 ] ; int len = array . length ; for ( int i = 0 ; i < len ; i ++ ) { if ( max < array [

第九章:内部排序

被刻印的时光 ゝ 提交于 2019-12-10 21:59:13
排序:将一个数据元素(或记录)的任意序列,重新排列成一个按关键字有序的序列。 稳定性——若两个记录A和B的关键字值相等,且排序后A、B的先后次序保持不变,则称这种排序算法是稳定的。 1.插入排序 思想:每步将一个待排序的对象,按其关键码大小,插入到前面已经排好序的一组对象的适当位置上,直到对象全部插入为止。 简言之,边插入边排序,保证子序列中随时都是排好序的。 1) 直接插入排序 在已形成的有序表中线性查找,并在适当位置插入,把原来位置上的元素向后顺移 时间效率: 因为在最坏情况下,所有元素的比较次数总和为(0+1+…+n-1)→O(n^2)。 其他情况下也要考虑移动元素的次数。 故时间复杂度为O(n^2) 空间效率:仅占用1个缓冲单元——O(1) 算法的稳定性:稳定 直接插入排序算法的实现: void InsertSort ( SqList &L ) { //对顺序表L作直接插入排序 for ( i = 2; i <=L.length; i++) //假定第一个记录有序 { L.r[0]= L.r[i]; j=i-1 ; //先将待插入的元素放入“哨兵”位置 while(L[0] .key<L[j].key) { L.r[j+1]= L.r[j]; j-- ; } //只要子表元素比哨兵大就不断后移 L.r[j+1]= L.r[0]; //直到子表元素小于哨兵,将哨兵值送入 /

排序算法-基数排序(Java)

前提是你 提交于 2019-12-10 18:57:08
package com.rao.sort; import java.util.*; /** * @author Srao * @className RadioSort * @date 2019/12/10 18:17 * @package com.rao.sort * @Description 基数排序 */ public class RadioSort { /** * 基数排序 * @param arr * @return */ public static int[] radioSort(int[] arr){ //1.找出最大值 int n = arr.length; int max = arr[0]; for (int i = 1; i < n; i++) { if (max < arr[i]){ max = arr[i]; } } //2.求出对大值的位数 int num = 1; while (max / 10 > 0){ num++; max /= 10; } //3.创建桶 List<LinkedList<Integer>> bucketList = new ArrayList<>(10); //4.初始化桶 for (int i = 0; i < 10; i++) { bucketList.add(new LinkedList<>()); } //5

c/c++实现基数排序

戏子无情 提交于 2019-12-09 16:22:56
基数排序 - 桶排序的改进版,桶的大小固定为10,减少了内存空间的开销。首先,找出待排序列中得最大元素max,并依次按max的低位到高位对所有元素排序;桶元素10个元素的大小即为待排序数列元素对应数值为相等元素的个数,即每次遍历待排序数列,桶将其按对应数值位大小分为了10个层级,桶内元素值得和为待排序数列元素个数。 时间复杂度:O(x*N)   稳定性:稳定 /*基数排序*/ //1. 计数排序,按整形数值单位进行排序 void countSort ( vector < int > & arr , int exp ) { int bucket [ 10 ] = { 0 } ; int arrSize = arr . size ( ) ; int * pTemp = new int [ arrSize ] ; memset ( pTemp , 0 , arrSize * sizeof ( int ) ) ; //统计单位exp各数值计数值 for ( auto const val : arr ) ++ bucket [ ( val / exp ) % 10 ] ; //计数分层 for ( int i = 1 ; i < 10 ; ++ i ) bucket [ i ] + = bucket [ i - 1 ] ; //按exp位大小用数组arr元素填充pTemp for ( int