2017-10-13 12:09:57 +03:00
|
|
|
/*
|
2020-05-29 23:23:24 +03:00
|
|
|
* Algorithm : Bucket Sort
|
|
|
|
* Time-Complexity : O(n)
|
|
|
|
*/
|
|
|
|
#include <assert.h>
|
2017-10-13 12:09:57 +03:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
2020-05-29 23:23:24 +03:00
|
|
|
#define NARRAY 8 /* array size */
|
|
|
|
#define NBUCKET 5 /* bucket size */
|
2017-10-13 12:09:57 +03:00
|
|
|
#define INTERVAL 10 /* bucket range */
|
|
|
|
|
2018-03-20 17:06:16 +03:00
|
|
|
struct Node
|
|
|
|
{
|
|
|
|
int data;
|
|
|
|
struct Node *next;
|
2017-10-13 12:09:57 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
void BucketSort(int arr[]);
|
|
|
|
struct Node *InsertionSort(struct Node *list);
|
|
|
|
void print(int arr[]);
|
|
|
|
void printBuckets(struct Node *list);
|
|
|
|
int getBucketIndex(int value);
|
|
|
|
|
|
|
|
void BucketSort(int arr[])
|
2018-03-20 17:06:16 +03:00
|
|
|
{
|
2020-05-29 23:23:24 +03:00
|
|
|
int i, j;
|
2018-03-20 17:06:16 +03:00
|
|
|
struct Node **buckets;
|
|
|
|
|
|
|
|
/* allocate memory for array of pointers to the buckets */
|
2020-05-29 23:23:24 +03:00
|
|
|
buckets = (struct Node **)malloc(sizeof(struct Node *) * NBUCKET);
|
2018-03-20 17:06:16 +03:00
|
|
|
|
|
|
|
/* initialize pointers to the buckets */
|
2020-05-29 23:23:24 +03:00
|
|
|
for (i = 0; i < NBUCKET; ++i)
|
2018-03-20 17:06:16 +03:00
|
|
|
{
|
|
|
|
buckets[i] = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* put items into the buckets */
|
|
|
|
/* creates a link list in each bucket slot */
|
2020-05-29 23:23:24 +03:00
|
|
|
for (i = 0; i < NARRAY; ++i)
|
2018-03-20 17:06:16 +03:00
|
|
|
{
|
|
|
|
struct Node *current;
|
|
|
|
int pos = getBucketIndex(arr[i]);
|
2020-05-29 23:23:24 +03:00
|
|
|
current = (struct Node *)malloc(sizeof(struct Node));
|
2018-03-20 17:06:16 +03:00
|
|
|
current->data = arr[i];
|
|
|
|
current->next = buckets[pos];
|
|
|
|
buckets[pos] = current;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* check what's in each bucket */
|
2020-05-29 23:23:24 +03:00
|
|
|
for (i = 0; i < NBUCKET; i++)
|
2018-03-20 17:06:16 +03:00
|
|
|
{
|
|
|
|
printf("Bucket[\"%d\"] : ", i);
|
|
|
|
printBuckets(buckets[i]);
|
|
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* sorting bucket using Insertion Sort */
|
2020-05-29 23:23:24 +03:00
|
|
|
for (i = 0; i < NBUCKET; ++i)
|
2018-03-20 17:06:16 +03:00
|
|
|
{
|
|
|
|
buckets[i] = InsertionSort(buckets[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* check what's in each bucket */
|
2017-10-13 12:09:57 +03:00
|
|
|
printf("--------------\n");
|
|
|
|
printf("Buckets after sorted\n");
|
2020-05-29 23:23:24 +03:00
|
|
|
for (i = 0; i < NBUCKET; i++)
|
2018-03-20 17:06:16 +03:00
|
|
|
{
|
|
|
|
printf("Bucket[\"%d\"] : ", i);
|
|
|
|
printBuckets(buckets[i]);
|
|
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* put items back to original array */
|
2020-05-29 23:23:24 +03:00
|
|
|
for (j = 0, i = 0; i < NBUCKET; ++i)
|
2018-03-20 17:06:16 +03:00
|
|
|
{
|
|
|
|
struct Node *node;
|
|
|
|
node = buckets[i];
|
2020-05-29 23:23:24 +03:00
|
|
|
while (node)
|
2018-03-20 17:06:16 +03:00
|
|
|
{
|
|
|
|
// precondition for avoiding out of bounds by the array
|
|
|
|
assert(j < NARRAY);
|
|
|
|
arr[j++] = node->data;
|
|
|
|
node = node->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* free memory */
|
2020-05-29 23:23:24 +03:00
|
|
|
for (i = 0; i < NBUCKET; ++i)
|
2018-03-20 17:06:16 +03:00
|
|
|
{
|
|
|
|
struct Node *node;
|
|
|
|
node = buckets[i];
|
2020-05-29 23:23:24 +03:00
|
|
|
while (node)
|
2018-03-20 17:06:16 +03:00
|
|
|
{
|
|
|
|
struct Node *tmp;
|
|
|
|
tmp = node;
|
|
|
|
node = node->next;
|
|
|
|
free(tmp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free(buckets);
|
|
|
|
return;
|
2017-10-13 12:09:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Insertion Sort */
|
|
|
|
struct Node *InsertionSort(struct Node *list)
|
2018-03-20 17:06:16 +03:00
|
|
|
{
|
2020-05-29 23:23:24 +03:00
|
|
|
struct Node *k, *nodeList;
|
2018-03-20 17:06:16 +03:00
|
|
|
/* need at least two items to sort */
|
2020-05-29 23:23:24 +03:00
|
|
|
if (list == NULL || list->next == NULL)
|
2018-03-20 17:06:16 +03:00
|
|
|
{
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
|
|
|
nodeList = list;
|
|
|
|
k = list->next;
|
|
|
|
nodeList->next = NULL; /* 1st node is new list */
|
2020-05-29 23:23:24 +03:00
|
|
|
while (k != NULL)
|
2018-03-20 17:06:16 +03:00
|
|
|
{
|
|
|
|
struct Node *ptr;
|
|
|
|
/* check if insert before first */
|
2020-05-29 23:23:24 +03:00
|
|
|
if (nodeList->data > k->data)
|
2018-03-20 17:06:16 +03:00
|
|
|
{
|
|
|
|
struct Node *tmp;
|
|
|
|
tmp = k;
|
2020-06-28 18:25:37 +03:00
|
|
|
k = k->next; // important for the while
|
2018-03-20 17:06:16 +03:00
|
|
|
tmp->next = nodeList;
|
|
|
|
nodeList = tmp;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// from begin up to end
|
|
|
|
// finds [i] > [i+1]
|
2020-05-29 23:23:24 +03:00
|
|
|
for (ptr = nodeList; ptr->next != NULL; ptr = ptr->next)
|
2018-03-20 17:06:16 +03:00
|
|
|
{
|
2020-05-29 23:23:24 +03:00
|
|
|
if (ptr->next->data > k->data)
|
|
|
|
break;
|
2018-03-20 17:06:16 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// if found (above)
|
2020-05-29 23:23:24 +03:00
|
|
|
if (ptr->next != NULL)
|
2018-03-20 17:06:16 +03:00
|
|
|
{
|
|
|
|
struct Node *tmp;
|
|
|
|
tmp = k;
|
2020-06-28 18:25:37 +03:00
|
|
|
k = k->next; // important for the while
|
2018-03-20 17:06:16 +03:00
|
|
|
tmp->next = ptr->next;
|
|
|
|
ptr->next = tmp;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ptr->next = k;
|
2020-06-28 18:25:37 +03:00
|
|
|
k = k->next; // important for the while
|
2018-03-20 17:06:16 +03:00
|
|
|
ptr->next->next = NULL;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nodeList;
|
2017-10-13 12:09:57 +03:00
|
|
|
}
|
|
|
|
|
2020-05-29 23:23:24 +03:00
|
|
|
int getBucketIndex(int value) { return value / INTERVAL; }
|
2017-10-13 12:09:57 +03:00
|
|
|
|
|
|
|
void print(int ar[])
|
2018-03-20 17:06:16 +03:00
|
|
|
{
|
|
|
|
int i;
|
2020-05-29 23:23:24 +03:00
|
|
|
for (i = 0; i < NARRAY; ++i)
|
2018-03-20 17:06:16 +03:00
|
|
|
{
|
|
|
|
printf("%d ", ar[i]);
|
|
|
|
}
|
|
|
|
printf("\n");
|
2017-10-13 12:09:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void printBuckets(struct Node *list)
|
|
|
|
{
|
2018-03-20 17:06:16 +03:00
|
|
|
struct Node *cur = list;
|
2020-05-29 23:23:24 +03:00
|
|
|
while (cur)
|
2018-03-20 17:06:16 +03:00
|
|
|
{
|
|
|
|
printf("%d ", cur->data);
|
|
|
|
cur = cur->next;
|
|
|
|
}
|
2017-10-13 12:09:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
int main(void)
|
2018-03-20 17:06:16 +03:00
|
|
|
{
|
2020-05-29 23:23:24 +03:00
|
|
|
int array[NARRAY] = {29, 25, -1, 49, 9, 37, 21, 43};
|
2017-10-13 12:09:57 +03:00
|
|
|
|
|
|
|
printf("Initial array\n");
|
|
|
|
print(array);
|
|
|
|
printf("------------\n");
|
|
|
|
|
2018-03-20 17:06:16 +03:00
|
|
|
BucketSort(array);
|
2017-10-13 12:09:57 +03:00
|
|
|
printf("------------\n");
|
2018-03-20 17:06:16 +03:00
|
|
|
printf("Sorted array\n");
|
|
|
|
print(array);
|
|
|
|
return 0;
|
|
|
|
}
|