如何使用链表实现计数排序?
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++;
}
我想做的是使用 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++;
}