基數排序-單連結串列實現【資料結構與演算法分析(c 語言描述)】

jerrkill發表於2018-12-23

實現思路

基數排序本身是一個:分配-收集 過程

  1. 將一組需要排序的數,用連結串列儲存 記為 L
  2. 用一組連結串列的來存放分配的節點 N[0-9]
  3. 遍歷 L 每個節點分配到對應的 N[0-9]
  4. 將 N[0-9] 重新收集到 L
  5. 反覆重複 3-4 直到最高位結束, 排序結束 ,
  6. L 就變成了有序

排序過程

待排序數
64 8 216 512 27 729 0 1 343 125
第一次分配
N0 0
N1 1
N2 512
N3 343
N4 64
N5 125
N6 216
N7 27
N8 8
N9 729
收集
0->1->512->343->64->125->216->27->8->729
第二次分配
N0 0->1->8
N1 512->216
N2 125->27->729
N3
N4 343
N5
N6 64
N7
N8
N9
收集
0->1->8->512->516->125->27->729->343->64
....
類推

程式碼實現

/**
 * 基數排序-單連結串列實現
 */

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define Error(Str) FatalError(Str)
#define FatalError(Str) fprintf(stderr,"%s\n",Str),exit(1)

#define N 10 //數個數
#define RADIX 10 //基數
#define POS_LEN 3 //位長

typedef struct Node
{
    int data;
    struct Node *next;
} *pNode;
typedef pNode LNode;

pNode create();
int get_num_pos(int num, int pos, int radix);
void radix_sort(pNode collect, int radix, int pos_len);
void append_node(pNode L, int num);
void insert(pNode P, int num);
void delete_list(pNode L);
void test();
void print(pNode L);

int main(void)
{
    test();
    return 0;
}

void radix_sort(pNode collect, int radix, int pos_len)
{
    // collect assign
    LNode assign[radix - 1], P, tmp, p;
    int i, num;
    for (i = 0; i < radix; i++) {
        assign[i] = create();
    }
    for (i = 1; i <= pos_len; i++) {
        P = collect;
        while (NULL != P->next) {
            p = P->next;
            P->next = p->next;
            p->next = NULL;
            int num = get_num_pos(p->data, i, radix);
            tmp = assign[num];
            while (NULL != tmp->next) {
                tmp = tmp->next;
            }
            tmp->next = p;
        }
        printf("第%d次分配\n", i);
        for (int j = 0; j < radix; j++) {
            printf("N-%d\t", j);
            print(assign[j]);
        }

        //assign
        P = collect;
        for (int j = 0; j < radix; j++) {
            LNode phead;
            phead = assign[j];
            while (NULL != phead->next) {
                p = phead->next;
                phead->next = p->next;
                p->next = NULL;
                P->next = p;
                P = P->next;
            }
        }
        printf("第%d次收集\n", i);
        print(collect);
        // 置空
        // for (int j = 0; j < radix; j++) {
        //  delete_list(assign[j]);
        // }
    }
    // free space
    for (i = 0; i < radix; i++) {
        delete_list(assign[i]);
    }
}

int get_num_pos(int num, int pos, int radix)
{
    int temp = 1, i;
    for (i = 0; i < pos - 1; i++)
        temp *= radix;
    return (num / temp) % radix;
}
void insert(pNode P, int num)
{
    pNode temp;
    temp = (pNode)malloc(sizeof(struct Node));
    if (NULL == temp)
        FatalError("out of space");
    temp->data = num;
    temp->next = NULL;
    P->next = temp;
}

void append_node(pNode L, int num)
{
    pNode temp, P;
    P = L;
    temp = (pNode)malloc(sizeof(struct Node));
    if (NULL == temp)
        FatalError("out of space");
    temp->next = NULL;

    while (NULL != P->next) {
        P = P->next;
    }
    P->next = temp;
}

pNode create()
{
    pNode L;
    L = (pNode)malloc(sizeof(struct Node));
    if (NULL == L)
        FatalError("out of space");
    L->next = NULL;
    return L;
}

void delete_list(pNode L)
{
    pNode P, temp;
    P = L->next;
    L->next = NULL;
    while (NULL != P) {
        temp = P->next;
        free(P);
        P = temp;
    }
}

void print(pNode L)
{
    pNode P;
    P = L->next;
    while (NULL != P)
    {
        printf("%d\t", P->data);
        P = P->next;
    }
    printf("\n");
}

void test()
{
    pNode source, tmp, P;
    int arr[N] = {64, 8, 216, 512, 27, 729, 0, 1, 343, 125};
    int i;
    int max = 1;
    for (i = 0; i <= POS_LEN - 1; i++)
        max *= RADIX;
    source = create();
    P = source;
    srand((unsigned)time(NULL));
    for (i = 0; i < N; i++) {
        insert(P, arr[i]);
        P = P->next;
    }
    print(source);
    radix_sort(source, RADIX, POS_LEN);
    printf("結果\n");
    print(source);
}

執行截圖

file

高度自律,深度思考,以勤補拙

相關文章