#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
/*
十位 0~9 低位优先 链式队列 (若顺序,则浪费空间大,某一时刻有可能全进一个队列)
先放个位 后出队
第一遍后 个位从小到大有序
第二遍后 十位从小到大有序
*/
typedef struct Node
{
int data;
struct Node *next;
}Node;
typedef struct HNode//队列的类型
{
struct Node *front;
struct Node *rear;
}HNode,*PQueue;
Node *BuyNode(int val)
{
Node *p = (Node *)malloc(sizeof(Node));
assert(p != NULL);
p->data = val;
p->next = NULL;
return p;
}
void InitQueue(PQueue pq)//初始化
{
assert(pq != NULL);
pq->front = NULL;
pq->rear = NULL;
}
void Push(PQueue pq, int val)//入队
{
Node *p = BuyNode(val);
/*if (pq->front == NULL)//第一次插 需要注意
{
pq->front = p;
pq->rear = p;
}
pq->rear->next = p;
pq->rear = p;*/ // pq的尾指针需要指向队尾
if (pq->front == NULL)//第一次插 需要注意
{
pq->front = p;
}
else
{
pq->rear->next = p;
}
pq->rear = p;
}
//获取队头的值
bool Pop(PQueue pq, int *rtval)
{
if (pq->rear == NULL)//队头队尾效果一样
{
return false;
}
Node *p = pq->front;
*rtval = p->data;
pq->front = p->next;
free(p);
if (pq->front == NULL)//防止最后一个为野指针
{
pq->rear = NULL;
}
return true;
}
//得到十进制数字num右数第figure位的值
//例如 (123,0)
int GetFigure(int num, int figure)
{
for (int i = 0; i < figure; i++)
{
num /= 10;
}
return num % 10;
}
//figure 从0开始
void Radix(int *arr, int len, int figure)//figure 右数第几位 作为关键字
{
HNode head[10];
int i ,key;
for (i = 0; i < 10; i++)
{
InitQueue(&head[i]);//O(n)
}
for (i = 0; i < len; i++)//进
{
key = GetFigure(arr[i], figure);//例如 key=(123,0)=3
Push(&head[key], arr[i]);
}
int j = 0;//桶号
for (i = 0; i < len;)//出
{
if (Pop(&head[j], &arr[i]))//j号桶内有数字
{
i++;
}
else//出失败 说明当前没数据
{
j++;
}
}
}
int GetMaxFigure(int *arr, int len)//判断最大值的位数 比较的趟数
{
int max = arr[0];
int count = 0;
for (int i = 0; i < len; i++)
{
if (max < arr[i])
{
max = arr[i];
}
}
do //杜绝0的判断
{
count++;
max /= 10;
} while (max != 0);
return count;
}
void RadixSort(int *arr, int len)
{
int count = GetMaxFigure(arr, len);
for (int i = 0; i < count; i++)
{
Radix(arr,len,i);
}
}
void Show(int *arr, int len)
{
for (int i = 0; i < len; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
int main()
{
int arr[] = { 4,9,6,8,5,7 };
int len = sizeof(arr) / sizeof(arr[0]);
RadixSort(arr, len);
Show(arr, len);
return 0;
}