如何使用链表实现计数排序?

How do implement Count sort using linked list?

我想做的是使用 linked 列表创建计数排序,这样我就可以 link 同一索引中的两个相似元素,然后从左到右复制到原始数组。但是我的 Buckets[i] 即使在插入之后也总是 NULL 。所以我得到的数组不会改变。我不知道我做错了什么。

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

struct Node {
    int data;
    struct Node *next;
} **Buckets;

void printArray(int arr[], int size) {
    for (int i = 0; i < size; i++)
        printf("%d ", arr[i]);
    printf("\n");
}

int findMax(int A[], int n) {
    int i, max = A[0];
    for (i = 0; i < n; i++) {
        if (A[i] > max)
            max = A[i];
    }
    return max;
}
void Insert(struct Node *p, int x) {
    while (p != NULL) {
        p = p->next;
    }
    Node *t = t = (struct Node *)malloc(sizeof(struct Node));
    t->data = x;
    t->next = NULL;
    p = t;
}

int Delete(struct Node *Buckets) {
    while (Buckets->next != NULL) {
        Buckets = Buckets->next;
    }
    int temp = Buckets->data;
    free(Buckets);
    return temp;
}

void BucketSort(int A[], int size) {
    int max, i, j;
    max = findMax(A, size);

    Buckets = new Node * [max + 1];
    for (i = 0; i < max + 1; i++) {
        Buckets[i] = NULL;
    }
    for (i = 0; i < size; i++) {
        Insert(Buckets[A[i]], A[i]); //insertion
    }
    i = j = 0;
    while (i < max + 1) {
        while (Buckets[i] != NULL) {
            A[j++] = Delete(Buckets[i]); // copy back in array
        }
        i++;
    }
}

int main() {
    int arr[] = { 3, 8, 5, 1, 10 };
    int size = sizeof(arr) / sizeof(arr[0]); //5
    printf("\nBefore : ");
    printArray(arr, size);

    BucketSort(arr, size);

    printf("\nAfter : ");
    printArray(arr, size);

    return 0;
}

您的 Insert 函数并没有真正修改列表——您只是将新节点分配给局部变量,该变量立即超出范围。

您可以通过将指向节点指针的指针传递给函数来解决这个问题。该指针首先指向头指针,然后在前进时指向前一个节点的 next 成员:

void Insert(struct Node **p, int x)
{
    while (*p) p = &(*p)->next;

    *p = new Node(x);     // assume a c'tor here
}

像这样调用函数:

for (i = 0; i < size; i++) {
    Insert(&Buckets[A[i]] ,A[i]);
}

删除同理:删除时必须修改链接或列表头:

int Delete(struct Node **p)
{
    int temp = (*p)->data;
    struct Node *del = *p;

    *p = (*p)->next;

    delete del;
    return temp;
}

(此代码提取头节点,这可能是您想要的:您在末尾插入,然后从头开始检索。这应该保留原始顺序。在您的情况下并不重要,您在哪里除了 int 之外没有数据。)

像这样调用Delete

i = j = 0;
while (i < max + 1) {
    while (Buckets[i]) {
        A[j++] = Delete(&Buckets[i]); 
    }
    i++;
}