桶排序
基数算法(Radix Sort)(桶排序):按照多个关键字进行排序的方法
将所有数据从最低位开始调整,例如个位、十位、百位等等,判断需要几次,需要通过数据中的最大值的位数去决定。
例如,数据中的最大值史999,则所有数据需要进行个位、十位、百位的排序。
可以判断出这种排序适合于所有的数据位数差别不大的情景。
桶:队列(先进先出)
10个桶(0-9)
时间复杂度:O(kn)
空间复杂度:O(n) k是关键字的最大位数
稳定性:稳定(没有有跳跃式的交换数据,没有交换数据)
实现过程
具体实现
#include <iostream>
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include <queue>
using namespace std;
#define DATANUM 15
void Show(int* arr, int length)
{
for (int i = 0; i < length; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
int IsOrder(int* arr, int length)
{
for (int i = 0; i < length - 1; i++)
{
if (arr[i] > arr[i + 1])
{
return 0;
}
}
return 1;
}
int GetMaxWidth(int* arr, int length)
{
int max = arr[0];
for (int i = 1; i < length; i++)
{
if (arr[i] > max)
{
max = arr[i];
}
}
int width = 0;
while (max)
{
width++;
max = max / 10;
}
return width;
}
int GetNum(int data, int width)
{
int num = data % 10;
while (width)
{
data /= 10;
num = data % 10;
width--;
}
return num;
}
//根据width的值所代表的位数进行排序:0:个位 1:十位 2:百位
void Radix(int* arr, int len, int width)
{
//1.创建10个队列
queue<int> bucket[10];
//2.把值按照对应的width位放入对应的桶中
//扫描arr中的元素,根据width的值获取相应的位数值将其Push到相应的队列中
for (int i = 0; i < len; i++)
{
int num = GetNum(arr[i], width);//获取数据第width位的值
bucket[num].push(arr[i]);
}
//3.从0-9号桶依次将值取出来
//将队列中的所有数据都获取出来,存储到arr中
int index = 0;
for (int i = 0; i < 10; i++)//0-9号桶
{
while (!bucket[i].empty())
{
arr[index] = bucket[i].front();
bucket[i].pop();
index++;
}
}
}
void RadixSort(int* arr, int length)
{
assert(arr != NULL || length > 1);
if (arr == NULL || length < 2)
{
printf("RadixSort:Invalid Array\n");
return;
}
//获取最大值的位数,获取排序的次数
int width = GetMaxWidth(arr, length);
for (int i = 0; i < width; i++)
{
Radix(arr, length, i);
}
}
int main()
{
int arr[DATANUM];
for (int i = 0; i < DATANUM; i++)
{
arr[i] = rand() % 100;
}
printf("Before RadixSort:");
Show(arr, DATANUM);
RadixSort(arr, DATANUM);
if (IsOrder(arr, DATANUM))
{
printf("After RadixSort:");
Show(arr, DATANUM);
}
else
{
printf("Failed RadixSort\n");
}
return 0;
}