基数排序
来源:互联网 发布:mac 查看安装路径 编辑:程序博客网 时间:2024/06/04 00:43
基数排序:
在待排序序列中,每个数据在各个数位上可能的取值总数称为基数。如:在十进制中,数据某一位的取值为0~9,那么基数就是10.
在八进制排序中,基数就是8.
基数排序方法有两种:一种是最高位优先(MSD),另一种是最低位优先(LSD)。
以MSD为例:
基数排序需要以下步骤:
生成count数组、将待排序元素放入对应的桶中、将排好序的桶中的元素再复制到原数组中的对应位置、递归(d由最高位转换到次高位)
(1)count[k]数组:
第i位取值为k的元素有count[k]个。
当基数为10时,k取0~9.
待排序元素:[left,right]
生成count数组,要取数据任一位的值,为此,设计一个位取数器:位取数器:
input:数据 位数
output:该位的取值
int getdigit(int num,int dt) //位取数器,num,适用范围:0~999
{
int g;
if(dt==3)
{
if(num>=0&&num<=9)
return 0;
else if(num>=10&&num<=99)
return 0;
else
return num/100;
}
if(dt==2)
{
if(num>=0&&num<=9)
return 0;
else if(num>=10&&num<=99)
return num/10;
else
{
g=num/100;
return (num-g*100)/10;
}
}
if(dt==1)
{
if(num>=0&&num<=9)
return num;
else if(num>=10&&num<=99)
{
g=num/10;
return num-g*10;
}
else
{
g=num/10;
return num-g*10;
}
}
return 0;
}
(2)用辅助数组auxArray[len]来模拟桶,每个桶的大小由count[k]来确定。
要确定每个桶在auxArray[len]中的位置:
假设有count[k]数组:
从count[k]中可以看出共有12个待排序元素,分布在0~9共10个桶中。
每个桶的位置在auxArray[12]中如下:
(4、8号桶不存在,即没有这样的待排序元素)
即:第k号桶的首个位置是:auxArray[count[0]+count[1]+…+count[k-1]]
第k号桶的下一个位置是:
auxArray[count[0]+count[1]+…+count[k-1]+1+…]现在开始将待排序的元素放到对应的桶中:
桶分两种情况:
1、 能装1个元素
2、 能装多个元素
为此,要对每一个桶设置一个计数器。在桶中每放入一个元素,这个桶的计数器就加1。在桶中放入元素前,先检测计数器,用计数器来确定要放入的位置。计数器设置:
cnt[10]
初始化:int cnt[10]=0;
for(i=left;i<=right;i++)//扫描待排序元素
{ firstPos=0;//桶的首位置归零
bucket=a[i]/x; //确定哪个桶
for(j=0;j<=bucket-1;j++) //确定桶的首位置
{
firstPos=firstPos+count[j];
}
auxArray[firstPos+cnt[bucket]]=a[i];
cnt[bucket]++; //记录这个桶的下一个位置
}
(3)将排好序的桶中的元素再复制到原数组中的对应位置:
要考虑auxArray[]与a[]的对应关系:
若原数组为:a[left,right]
再假设:count[2]=1 count[3]=2 count[4]=1
那么:auxArray[]:
可以看出auxArray的大小与count[k]有关。
即auxArray[count[0]+count[1]+…+count[9]]
而且:auxArray[0]对应a[left],auxArray[1]对应a[left+1]…for(i=0;i<count[0]+…+count[9];i++)
a[left+i]=auxArray[i];
(4)递归:
由最高位转换到次高位;
递归结束的条件:if(d>0)
要确定递归的桶(即存在多个元素的桶)和这些桶的边界。
a[left,right]对应了0~9号桶。例如:
count[]:
a[](原数组):
需要递归的桶为:1、2、5、7
它们的起始下标(st)表示:
1:left+(count[0])
2:left+(count[0]+count[1])
5:left+(count[0]+count[1]+…+count[4])
7:left+(count[0]+…+count[6])
它们的终止下标表示:
1:st+count[1]-1
2:st+count[2]-1
5:st+count[5]-1
7:st+count[7]-1
for(i=0;i<10;i++)
{ s=0;st=0;ed=0;//归零
if(count[i]>1)//需要递归的桶
{
for(j=0;j<i;j++)
{
s=s+count[j];
}
st=left+s; //第i个桶的起始下标
ed=st+count[i]-1; //第i个桶的终止下标
}
radixsort(a,st,ed,d-1);
}总结:一定要注意变量的适用范围(是否需要在下一次循环开始前置零) 声明的变量和数组要初始化
附程序:
// node.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <string.h>#include <stdlib.h>#define len 14void radixsort(int t[],int left,int right,int d);int getdigit(int num,int dt);int getdigit(int num,int dt) //位取数器{int g;if(dt==3){if(num>=0&&num<=9) return 0;else if(num>=10&&num<=99) return 0;else return num/100;}if(dt==2){if(num>=0&&num<=9) return 0;else if(num>=10&&num<=99) return num/10;else {g=num/100;return (num-g*100)/10;}}if(dt==1){if(num>=0&&num<=9) return num;else if(num>=10&&num<=99){g=num/10; return num-g*10;}else {g=num/10;return num-g*10;}} return 0;}void radixsort(int t[],int left,int right,int d){ if(d>0) //递归结束的条件 {//产生count数组 int m,n,sum,w; int count[10]={0}; for(m=left;m<=right;m++) { w=getdigit(t[m],d); count[w]++; } sum=0; for(n=0;n<10;n++)sum=sum+count[n];//将待排序元素放入对应的桶中 int cnt[10]={0};intauxArray[len]={0};int bucket,firstPos,i,j; for(i=left;i<=right;i++){firstPos=0;bucket=getdigit(t[i],d);for(j=0;j<=bucket-1;j++){ firstPos=firstPos+count[j];} auxArray[firstPos+cnt[bucket]]=t[i]; cnt[bucket]++;}//将桶中的元素返回给原数组 int k; for(k=0;k<sum;k++) t[left+k]=auxArray[k];/*int tt;for(tt=0;tt<len;tt++){printf("%d",t[tt]);printf("\t");}printf("\n");*///递归int a,b,s,st,ed;for(a=0;a<10;a++){s=0;st=0;ed=0;if(count[a]>1){for(b=0;b<a;b++)s=s+count[b]; st=left+s; ed=st+count[a]-1;}radixsort(t,st,ed,d-1);}}//if}void main(int argc, char* argv[]){int b[len]={361,9,667,26,587,3,666,103,500,79,325,46,518,45}; //increaseint r; int ttt;for(ttt=0;ttt<len;ttt++){printf("%d",b[ttt]);printf("\t");}printf("\n");radixsort(b,0,len-1,3); printf("\n");for(r=0;r<len;r++){printf("%d",b[r]);printf("\t");} printf("\n");}
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- STL常用容器用法之——stack
- tensorflow将训练好的模型freeze,即将权重固化到图里面,并使用该模型进行预测(tf.graph_util.convert_variables_to_constants函数)
- JSP img元素无法显示本地图片的问题(一)
- MyEclipse2017破解教程
- 网络基础常考面试题
- 基数排序
- 洛谷p1880石子合并
- 【win32】vs2010的窗体程序Helloworld
- Spring配置数据库连接池错误(特别注意)
- mysql5.5编译安装
- 利用Flask-AppBuilder 快速构建Web后台管理应用
- linux 配置DNS服务器
- 步进电机脱机状态实质
- 【PAT】【Advanced Level】1075. PAT Judge (25)