桶排序
桶排序(Bucket sort)或所谓的箱排序,是一个排序算法,工作的原理是将数组分到有限数量的桶里。每个桶再个别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序),最后依次把各个桶中的记录列出来记得到有序序列。桶排序是鸽巢排序的一种归纳结果。
桶排序的思想就是和分治法是一样的!!!
1. 算法步骤
- 设置一个定量的数组当作空桶子。
- 寻访序列,并且把数组元素一个一个放到对应的桶子去。
- 对每个不是空的桶子进行排序。
- 从不是空的桶子里把数组元素再放回原来的序列中。
2. 动图演示
动图无法演示,但算法实现的步骤很简单,大家可以参考网络上其它博主的动图即可
3.代码实现
3.1. 算法实现
#define NBUCKET 10 // 桶的数量
#define INTERVAL 10 // 每个桶能存放的元素个数
void print_arr(int* arr, int n) {
int i;
printf("%d", arr[0]);
for (i = 1; i < n; i++)
printf(" %d", arr[i]);
printf("\n");
}
struct Node* InsertionSort(struct Node* list) {
struct Node* k, * nodeList;
if (list == NULL || list->next == NULL) {
return list;//如果list位空或只有一个元素,就不用进行插入排序
}
nodeList = list;
k = list->next;//k用作工作指针,用于迭代
nodeList->next = NULL;//nodelist指向的节点为头节点,节点值最小
while (k != NULL) {
struct Node* ptr;
if (nodeList->data > k->data) {
struct Node* tmp;
tmp = k;
k = k->next;
tmp->next = nodeList;
nodeList = tmp;
continue;
}//k所指向的节点比nodelist小,直接交换即可
for (ptr = nodeList; ptr->next != 0; ptr = ptr->next) {
if (ptr->next->data > k->data)
break;
}
//如果k所指向的节点比nodelist大,先让ptr指向代操作节点的前节点
if (ptr->next != 0) {//如果ptr不是最后一个节点
struct Node* tmp;
tmp = k;
k = k->next;
tmp->next = ptr->next;
ptr->next = tmp;
continue;
}
else {//ptr为最后一个节点
ptr->next = k;
k = k->next;
ptr->next->next = 0;
continue;
}
}
return nodeList;
}
void bucket_sort(int* arr, int n) {
int i, j;
struct Node** buckets;
// 创建所有桶
buckets = (struct Node**)malloc(sizeof(struct Node*) * NBUCKET);
// 设置每个桶为空桶
for (i = 0; i < NBUCKET; ++i) {
buckets[i] = NULL;
}
// 根据规定,将 arr 中的每个元素分散存储到各个桶中
for (i = 0; i < n; ++i) {
struct Node* current;
int pos = arr[i] / 10; //根据规则,确定元素所在的桶,这个映射关系根据
//特定需要进行更改
//创建存储该元素的存储块,并连接到指定的桶中
current = (struct Node*)malloc(sizeof(struct Node));
current->data = arr[i];
current->next = buckets[pos];
buckets[pos] = current;//
}
// 调用自定义的排序算法,对各个桶进行排序
for (i = 0; i < NBUCKET; ++i) {
buckets[i] = InsertionSort(buckets[i]);
}
// 合并所有桶内的元素
for (j = 0, i = 0; i < NBUCKET; ++i) {
struct Node* node;
node = buckets[i];
while (node) {
arr[j++] = node->data;
node = node->next;
}
}
}
3.2. 测试程序
void main(int argc, char** argv) {
int n = 20;//待测试的数据长度
int i;
int* arr = (int*)malloc(sizeof(int) * n);
srand(time(0));
for (i = 0; i < n; i++)
arr[i] = rand() % 100;//随机生成20个位于0~99范围内的数值
printf("bucket_sort_before: ");
print_arr(arr, n);//打印排序前数组元素
bucket_sort(arr,n);//桶排序
printf("bucket_sort_after: ");
print_arr(arr, n);//打印桶排序后数组元素
free(arr);//记住释放内存
system("pause");
}