标签:int ++ length 基数排序 array counts
基数排序
基数排序(Radix Sort)是1887年由赫尔曼·何乐礼发明的,基数排序非常适合用于整数排序(尤其是非负整数)。
它的执行流程为:依次对个位数、十位数、百位数、千位数、万位数…,进行排序(从低位到高位)。
个位数、十位数、百位数的取值范围都是固定的0~9,可以使用计数排序对它们进行排序。
思考:如果先对高位排序,再对低位排序,是否可行?不可行。
基数排序图解
代码实现
// 找出数组中的最大值
int max = array[0];
for (int i = 1; i < array.length; i++) {
if (array[i] > max) {
max = array[i];
}
}
int[] newArray = new int[array.length]; // 开辟新数组来存放有序的元素
// 每一位的范围是[0,10)
int[] counts = new int[10]; // 存放每个元素出现的次数
// 计算最大值的位数
for (int i = 1; i < max; i *= 10) {
// 对i位数进行计数排序
// 统计每一位的次数
for (int j = 0; j < array.length; j++) {
counts[array[j] / i % 10]++;
}
// 次数累加前面所有的次数
for (int j = 1; j < counts.length; j++) {
counts[j] += counts[j - 1];
}
// 将旧数组中的值填充到新数组的合适位置
for (int j = array.length - 1; j >= 0; j--) {
newArray[--counts[array[j] / i % 10]] = array[j];
}
// 将新数组的值复制到旧数组中
for (int j = 0; j < newArray.length; j++) {
array[j] = newArray[j];
}
// 情况counts,便于下次使用
for (int j = 0; j < counts.length; j++) {
counts[j] = 0;
}
}
上面代码实现的基数排序最好、最坏、平均时间复杂度为O(d∗(n+k)),空间复杂度为O(n+k)(其中d是最大值的位数,k是每一位数的范围),属于稳定排序。
基数排序的另一种实现
// 计算出最大值
int max = array[0];
for (int i = 1; i < array.length; i++) {
if (array[i] > max) {
max = array[i];
}
}
// 开辟一个二维数组来存放元素
int[][] arrays = new int[10][array.length];
// 存放二维数组中每个数组放了多少个元素
int[] sizes = new int[10];
// 根据最大值的位数进行排序
for (int i = 1; i <= max; i *= 10) {
// 计算出每个元素的索引存放在二维数组对应的位置
for (int j = 0; j < array.length; j++) {
int index = array[j] / i % 10; // 元素对应的位数是多少,所在的数组就是多少
arrays[index][sizes[index]++] = array[j];
}
// 遍历二维数组中的元素放入原来的数组中
int t = 0;
for (int m = 0; m < arrays.length; m++) {
for (int n = 0; n < sizes[m]; n++) {
array[t++] = arrays[m][n];
arrays[m][n] = 0; // 清空二维数组
}
sizes[m] = 0; // 清空
}
}
上面代码实现的基数排序时间复杂度为O(dn),空间复杂度是O(kn+k) (其中d是最大值的位数,k是每一位数的范围)。
更多精彩内容关注本人公众号:架构师升级之路
标签:int,++,length,基数排序,array,counts 来源: https://blog.csdn.net/u022812849/article/details/106960877
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。