zl程序教程

您现在的位置是:首页 >  后端

当前栏目

计数排序,基数排序,桶排序

排序 计数 基数排序
2023-09-11 14:17:25 时间

转 http://blog.163.com/yuyang_tech/blog/static/216050083201382055821953/

与合并排序,堆排序,快速排序等基于比较的排序算法不同,计数排序,以及基数排序、桶排序是用非比较的一些操作来确定排序顺序的,计数排序、基数排序、桶排序是三种以线性时间运行的算法。


计数排序:
计数排序假设n个输入元素中的每一个都是介于0到k之间的整数,即输入的数据是具有上界的整数。
计数排序的基本思想就是对每一个输入元素x,确定出小于x的元素个数。有了这一信息,就可以把x直接放到它的最终输出数组中的位置上。例如,如果有17个元素小于x,则x就输入第18个输出位置。
下面为计数排序的代码:
//CountingSort.cpp
void CountingSort(int arrSrc[],int arrDst[],int arrLength,int upperLimit)
{
int* arrCount = new int[upperLimit+1];
 
for(int i=0;i<=upperLimit;i++)//初始化arrCount
arrCount[i] = 0;
 
for(int i=0;i<arrLength;i++)//arrCount[i]记录arrSrc[]中等于i的元素个数
arrCount[arrSrc[i]] += 1;
 
for(int i=1;i<=upperLimit;i++)//arrCount[i]记录arrSrc[]中小于等于i的元素个数
arrCount[i] += arrCount[i-1];
 
for(int i=arrLength-1;i>=0;i--)
{
arrDst[arrCount[arrSrc[i]]-1] = arrSrc[i];
arrCount[arrSrc[i]] -= 1;
}
 
delete []arrCount;
}
一个调用的实例: 
#include <iostream>
#include <stdlib.h>
using namespace std;
 
void CountingSort(int arrSrc[],int arrDst[],int arrLength,int upperLimit);
 
void main()
{
int arrLength = 10;
int upperLimit = 50;
 
int* a = new int[arrLength];
 
for(int i=0;i<arrLength;i++)
a[i]= rand()%(upperLimit+1);
 
for(int i=0;i<arrLength;i++)
cout << a[i] <<"  ";
cout << endl;
 
int* b = new int[arrLength];
CountingSort(a,b,arrLength,upperLimit);
 
for(int i=0;i<arrLength;i++)
cout << b[i] <<"  ";
cout << endl;
 
delete []b;
}

 

基数排序:
基数排序首先从最低有效位数字进行排序,然后重复这个过程,直到最高有效位数字排序完毕。一个实例如图所示。
在基数排序中,最重要的一点是 按位排序 使用的算法一定要是稳定的。
在常见的排序算法中,选择排序、快速排序、希尔排序、堆排序不是稳定的排序算法,而冒泡排序、插入排序、合并排序是稳定的排序算法。当然,基数排序也是稳定的。(参考
 
计数排序,基数排序,桶排序 - 钰 - 计算机视觉·图像处理
 
桶排序:(参考百度百科
桶排序也是基于一定的假设。假定:输入是由一个随机过程产生的[0, 1)区间上均匀分布的实数。将区间[0, 1)划分为n个大小相等的子区间(桶),每桶大小1/n:[0, 1/n), [1/n, 2/n), [2/n, 3/n),…,[k/n, (k+1)/n ),…将n个输入元素分配到这些桶中,对桶中元素进行排序,然后依次连接桶输入0 ≤A[1..n] <1辅助数组B[0..n-1]是一指针数组,指向桶(链表)。
在桶排序算法的代码中,假设输入是含n个元素的数组A,且每个元素满足0≤ A[i]<1。另外还需要一个辅助数组B[O..n-1]来存放链表实现的桶,并假设可以用某种机制来维护这些表。
桶排序的算法如下(伪代码表示),其中floor(x)是地板函数,表示不超过x的最大整数。
procedure Bin_Sort(var A:List);
begin
n:=length(A);
for i:=1 to n do
      将A[i]插到表B[floor(n*A[i])]中;
for i:=0 to n-1 do
     用插入排序对表B[i]进行排序;
将表B[0],B[1],...,B[n-1]按顺序合并;
end;
下图演示了桶排序作用于有10个数的输入数组上的操作过程。(a)输入数组A[1..10]。(b)在该算法的第5行后的有序表(桶)数组B[0..9]。桶i中存放了区间[i/10,(i+1)/10]上的值。排序输出由表B[O]、B[1]、...、B[9]的按序并置构成。
计数排序,基数排序,桶排序 - 钰 - 计算机视觉·图像处理