【问题标题】:How do implement Count sort using linked list?如何使用链表实现计数排序?
【发布时间】:2020-05-24 18:09:28
【问题描述】:

我想要做的是使用链表创建一个计数排序,这样我就可以在同一个索引中链接两个相似的元素,然后从左到右复制到原始数组。但是我的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;
}

【问题讨论】:

  • 欢迎来到 SO!这被标记为 C,但对我来说它看起来像 C++。有理由不使用 STL 和普通的 C++ 语法吗?此外,它感觉就像一个代码转储。您能否将代码最小化并尝试提供minimal reproducible example 或进一步解释您的思考过程?谢谢。
  • 当你插入一个新节点时,你遍历列表,然后将新节点分配给本地指针变量p,这不会更新列表或列表的头部。事实上,一旦您离开Insert,该节点的句柄就会消失。你可能想要一个指向那里的指针,然后分配*p = &lt;new node&gt;
  • @ggorlen 嘿,谢谢!!感谢您指出,下次我一定会用干净的代码提供更好的问题,问题已经解决。 ^^

标签: c sorting pointers linked-list counting-sort


【解决方案1】:

您的 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;
}

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

像这样拨打Delete

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

【讨论】:

  • 嗨,@MOehm 非常感谢您简化了这么多,现在我明白我做错了什么!
猜你喜欢
  • 2013-01-13
  • 2022-01-03
  • 1970-01-01
  • 2019-07-29
  • 1970-01-01
  • 1970-01-01
  • 2021-07-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多