1.基数排序:
基数排序是针对有多个关键字(每个关键字的权重不同)的排序算法: 炸金花(花色,数字)。
针对于一组整形数据: 按照权重划分(个位,十位,百位,千位 … )。
按照从小权重到大权重进行处理。对于一个数据,拿到这一位的值,将原始数据存储到相应的队列中。一共有关键字取值范围的队列(0,1,2,3,4,5,6,7,8,9)。整个数据序列全部放入到队列后,按照队列顺序将其中的数据全部Pop出来,在放回到数组中。
基数排序数据之间不需要比较。
2.基数排序逻辑图
此时待排序序列已经有序
3.队列代码:
/*
队列的代码:
*/
typedef struct
{
int *data;
int rear;
int head;
int size;
}Queue;
void InitQueue(Queue *que, int init_size)
{
if(que == NULL) exit(0);
init_size = init_size > 0 ? init_size:10;
que->data = (int*)malloc(sizeof(int) * init_size);
if(que->data == NULL) exit(0);
que->head = que->rear = 0;
que->size = init_size;
}
void ClearQueue(Queue *que)
{
if(que == NULL) exit(0);
que->head = que->rear = 0;
}
void PushQue(Queue *que, int value)
{
if(que == NULL) exit(0);
if(que->rear == que->size) return;
que->data[que->rear++] = value;
}
int EmptyQue(Queue *que)
{
if(que == NULL) exit(0);
if(que->head == que->rear) return 1;
return 0;
}
int PopQue(Queue *que)
{
if(que == NULL) exit(0);
if(EmptyQue(que)) return -1;
int reval = que->data[que->head];
que->head++;
return reval;
}
void DestroyQue(Queue *que)
{
if(que == NULL) exit(0);
free(que->data);
que->data = NULL;
que->head = que->rear = 0;
}
4.排序代码
// 获取最大数的位数
int GetMaxWidth(int *arr, int len)
{
int max_value = 0;
for(int i = 0; i < len; ++i)
{
if(arr[i] > max_value)
{
max_value = arr[i];
}
}
int width = 0;
while(max_value) // 1234 1234 % 10
{
width++;
max_value /= 10;
}
return width;
}
//根据位数获取相应位上的值
int GetWidthValue(int value, int width)
{
while(width)
{
if(value == 0) return 0;
width--;
value /= 10;
}
return value % 10;
}
/*
空间复杂度: O(d*n) d是关键字的取值范围
时间复杂度: O(w*n) w是关键字的个数
稳定性: 稳定
*/
void RadixSort(int *arr, int len)
{
Queue que[10];
for(int i = 0; i < 10; ++i)
{
InitQueue(&que[i], len);
}
int max_width = GetMaxWidth(arr, len);
for(int i = 0; i < max_width; ++i) // i==0 个位 i==1 十位
{
for(int j = 0; j < len; ++j) // 遍历整个待排序序列,按照i给定的位数将数据放到对应的队列中
{
int value = GetWidthValue(arr[j], i);
PushQue(&que[value], arr[j]);
}
int index = 0;
for(int k = 0; k < 10; ++k) // 遍历所有的队列,按照顺序将队列中的数据全部输出
{
while(!EmptyQue(&que[k]))
{
arr[index++] = PopQue(&que[k]);
}
ClearQueue(&que[k]);
}
}
for(int i = 0; i < 10; ++i)
{
DestroyQue(&que[i]);
}
}