进阶之路

首页 新随笔 管理

缅怀初学 C 时大学时光。用 C 模拟的基数排序。

时间复杂度 O(d*n),d 为不同数字数目,n 为待排元素个数。

分为: MSD(most significant digit) 和 LSD(least significant digit)两种方法。

MSD:从最高级别的 key 开始排序,每趟排序将所有元素分成 d 堆。

LSD:  从最低级别的 key 开始排序,所有元素一起排序,直到有序。

我这里用 C 实现 LSD 的程序如下:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define BASE_NUM 10
typedef struct Node
{
    int v;
    Node *next;
} LinkList;
LinkList *list[BASE_NUM] = {0};     /* 1. if use an array of integer ,?will be more convenient; 2. v also can save the index */

void release(LinkList *Base[])
{
    int i;
    Node *pre = NULL;
    for(i = 0; i < BASE_NUM; ++i)
    {
        if(list[i] == NULL) continue;
        do
        {
            pre = list[i];
            list[i] = list[i]->next;
            free(pre);
        }while(Base[i] != NULL);
    }
}

void radixSort(int data[], int length)
{
    Node *p[BASE_NUM] = {0};
    int maxData = 0, temV = 1, base_id;
    int i, k, sortTime = 1;

    for(i = 0; i < length; ++i)  // get the max value.
        maxData = data[i] > maxData ? data[i] : maxData;

    while(maxData >= temV)  // Allocation
    {
        for(i = 0; i < length; ++i){
            base_id = data[i] / temV % 10;
            Node *s = (Node*)malloc(sizeof(Node));
            s->v = data[i];
            s->next = NULL;
            if(list[base_id] == NULL){
                list[base_id] = s;
                p[base_id] = list[base_id];
            }else{
                p[base_id]->next = s;
                p[base_id] = p[base_id]->next;
            }
        }

        k = 0;
        for(i = 0; i < BASE_NUM; ++i) // take back
        {
            p[i] = list[i];
            while(p[i] != NULL)
            {
                data[k++] = p[i]->v;
                p[i] = p[i]->next;
            }
        }

        printf("第 %d 趟后: \n", sortTime++);  // print current numbers
        for(i = 0; i < length; ++i) 
            printf("%d\t", data[i]);
        printf("\n");

        release(list);
        temV *= BASE_NUM;
    }
}

void init(int data[], int length)
{
    /*srand(1);*/
    for(int i = 0; i < length; ++i)
        data[i] = rand()%1000;
}
int main()
{
    enum{ N = 10};
    int numbers[N], i;    
    init(numbers, N);

    printf("待排数据:\n");
    for(i = 0; i < N; ++i)
        printf("%d\t", numbers[i]);
    printf("\n");

    radixSort(numbers, N);

    printf("排序结果:\n");
    for(i = 0; i < N; ++i)
        printf("%d\t", numbers[i]);
    printf("\n");

    return 0;
}

shot

posted on 2014-05-03 16:05  进阶之路  阅读(400)  评论(0编辑  收藏  举报