#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;
}