单链表实现基数排序

《数据结构与算法分析》练习题系列。
书上第3章在讲解链表时举了一个基数排序的例子,给出了具体的思路,但没有给出程序,而且我大致搜了一下,发现大部分人都是用数组写的,所以我想试着用单链表实现。
关于什么是基数排序,这个书上有很详细的讲解,这里不再赘述。

单链表结构:

struct Node;
typedef struct Node *PtrToNode;
typedef PtrToNode List;
typedef PtrToNode Position;
typedef int ElementType;

struct Node
{
    ElementType Element;
    PtrToNode Next;
};

直接贴代码了,看着挺复杂的,因为要用到结构体数组。

/*功能:利用单链表实现基数排序*/
/*输入:待排序序列,序列元素个数,序列元素最高位数*/
/*输出:已排序序列首地址*/
int *RadixSort(int *arr, int N, int H)
{
    int cnt[10];//桶计数器  
    int temp, count;
    List L[10];//创建链表数组
    Position P[10];//指示链表当前位置

    for (int i = 0; i < 10; i++)//链表组初始化
        L[i] = InitList();

    for (int j = 0; j < H; j++)
    {
        for (int i = 0; i < 10; i++)
        {
            P[i] = L[i];//链表指向头结点
            cnt[i] = 0; //桶计数器清零
        }

        /*将序列元素分配到各个链表下*/
        for (int i = 0; i < N; i++)
        {
            temp = arr[i];
            temp = (temp / (int)pow(10, j)) % 10;
            P[temp] = InsertAfterP(arr[i], P[temp]);//P[temp]指向后一个单元并填充arr[i]
            cnt[temp]++;
        }

        /*按顺序收集分散在各个链表的元素*/
        for (int i = 0; i < 10; i++)//链表指向头结点
            P[i] = L[i];
        count = 0;
        for (int i = 0; i < 10; i++)
        {   
            for (int k = 0; k < cnt[i]; k++)//根据第i个桶的元素个数确定循环次数
            {
                P[i] = P[i]->Next;
                arr[count++] = P[i]->Element;//依次将各链表(即桶)中元素按序放回序列中
            }
        }
    }

    return arr;
}

该算法的时间复杂度是O(H*(N+B)),其中H是排序的趟数,也就是输入序列最高十进制位数,N是排序序列元素的个数,B是桶数,这里选取的桶数是10。

你可能感兴趣的:(算法设计与分析)