ReviewForJob——桶式排序+基数排序(==多次桶式排序)

来源:互联网 发布:业界良心音乐软件 编辑:程序博客网 时间:2024/06/05 09:24

【0】README

1)本文旨在 给出 ReviewForJob——桶式排序+基数排序(==多次桶式排序) 的 代码实现和代码分析;

2)桶式排序基础参见 http://blog.csdn.net/pacosonswjtu/article/details/49685749, 基数排序基础参见  http://blog.csdn.net/pacosonswjtu/article/details/49687193


【1】桶式排序

1)intro:桶式排序适用于 许多输入只是一些小的整数的case, 而这种输入数据是 小整数的case 下 使用 快速排序就小题大做了;(小整数,比如所有数据小于10)

2)输入数据: 输入数据 A1, A2, A3, ........,An 必须只由小于 M 的整数组成;因为桶只有 M 个,M 个 桶存储在数组中;如对10进制数字而言,桶取10;纸牌数字而言,桶取13;纸牌花色而言,桶取4;(你看到了,生活中,小整数本就直接或间接存在的)

3)桶式排序如何存储数据的? value == index(把value看做其存储在数组中的下标)(干货——桶式排序的核心)即 array[Ai] = Ai,如 array[1] = 1,对的,你没有看错,数字1 就存储在 下标为1的桶中,或以下标为1的链表中(链式存储);如果有多个1的话,就存储在 其 next 节点中;这样一来,头结点存储在数组下标为1的 链表 存储着输入的所有数字1;

4)源码实现如下:

#include <stdio.h>#include <malloc.h>#define ElementType int#define Error(str) printf("\n\t error: %s \n",str) struct Node;typedef struct Node *Node;struct Node{int value;Node next;};struct BucketSet;typedef struct BucketSet* BucketSet;struct BucketSet{int size;Node* array;};BucketSet initBucketSet();void printArray(ElementType* data, int size);Node createNode(int value);void bucketsort(Node* buckets, ElementType value);// allocate for new Node with value.Node createNode(int value){Node temp = (Node)malloc(sizeof(struct Node));if(temp==NULL){Error("failed createBucket() for out of space.");return NULL;}temp->next = NULL;temp->value = value;return temp;}// allocate the memory for the bucket and bucket ptrBucketSet initBucketSet(int size){BucketSet bucketSet;int i;// allocate memory for BucketSet.bucketSet = (BucketSet)malloc(sizeof(struct BucketSet));if(bucketSet==NULL){Error("failed initBucketSet() for out of space.");return NULL;}bucketSet->size = size;// allocate memory for BucketSet->buckets.bucketSet->array = (Node*)malloc(size * sizeof(Node));if(!bucketSet->array){Error("failed initBucketSet() for out of space.");return NULL;}// allocate memory for every unit in BucketSet->buckets.for(i=0; i<size; i++){bucketSet->array[i] = createNode(-1);if(bucketSet->array[i]==NULL){Error("failed initBucketSet() for out of space.");return NULL;}}return bucketSet;}// details of bucketSort for the input array data with sizevoid bucketsort(Node* buckets, ElementType value){Node temp = buckets[value]; // value is treated as index.while(temp->next){temp = temp->next;}temp->next = createNode(value);temp->next->value = value;}// 将桶中数据 copy 回 原来的数组中.void bucketsToArray(BucketSet bucketSet, ElementType* array){Node* buckets = bucketSet->array;Node temp;int size = bucketSet->size;int i, j=0;for(i=0; i<size; i++){temp = buckets[i];while(temp->next){array[j++] = temp->next->value;temp = temp->next;}}}void printArray(ElementType* data, int size){int i;for(i = 0; i < size; i++) printf("\n\t data[%d] = %d", i, data[i]); printf("\n\n");} 
#include "p189_bucket_sort.h"void main(){ BucketSet bucketSet;ElementType data[] = {9, 6, 3, 2, 7, 7, 1, 4, 1, 0, 3, 9, 1, 1};intsize = 14, capacity=10;int i;bucketSet = initBucketSet(capacity);if(bucketSet==NULL){return ;}  printf("\nbucketsort based on {9, 6, 3, 2, 7, 7, 1, 4, 1, 0, 3, 9, 1, 1}\n");// 对10以内的数字进行桶排序.for(i=0; i<size; i++){bucketsort(bucketSet->array, data[i]);}bucketsToArray(bucketSet, data);printArray(data, size);} 


对以上代码的分析(Analysis):void bucketsort(Node* buckets, ElementType value) :桶排序的函数声明 必须这样写,因为main 函数中通过循环传入输入数据就可以调用了,这也方便了 后续 基数排序的扩展,即 不要把 main函数中的循环 放入 bucketsort() 函数中去;


【2】基数排序

1)intro:基数排序等价于多次桶式排序;

2)基数排序中的桶式排序代码和 单纯的桶式排序代码有一点不一样:下面的代码可以看到, 基数排序中的桶式排序方法 一开始就要 计算 输入数据在某位上的数字,该数字作为 index 而不是整个 value 作为 index, 这和 单纯的桶式排序有点区别;

// get the integer under the bit.int singleBit(int value, int bit){int i=1;while(i++ < bit){value /= 10;}return value%10;}// details of bucketsort for input data. void bucketsort(Node* buckets, ElementType value, int bit) // 基数排序中的桶式排序代码{int index = singleBit(value, bit);Node temp = buckets[index]; // value is treated as direct or indirect index.while(temp->next){temp = temp->next;}temp->next = createNode(value);}
// details of bucketSort for the input array data with sizevoid bucketsort(Node* buckets, ElementType value) // 单纯的桶式排序代码{Node temp = buckets[value]; // value is treated as index.while(temp->next){temp = temp->next;}temp->next = createNode(value);temp->next->value = value;}
3)基数排序代码如下:
// get the integer under the bit.int singleBit(int value, int bit){int i=1;while(i++ < bit){value /= 10;}return value%10;}// details of bucketsort for input data. void bucketsort(Node* buckets, ElementType value, int bit){int index = singleBit(value, bit);Node temp = buckets[index]; // value is treated as direct or indirect index.while(temp->next){temp = temp->next;}temp->next = createNode(value);}
#include "p189_bucket_sort.h"//free the memory bucketSet->array own.void clearBuckets(BucketSet bucketSet){int i, size = bucketSet->size;Node* array = bucketSet->array;Node temp, tempcopy;for(i=0; i<size; i++){temp = array[i]->next;while(temp){tempcopy = temp;temp = temp->next;free(tempcopy);tempcopy = NULL;}array[i]->next = NULL;}}// 基于桶式排序的基数排序. (待排序元素个数为size)void radixsort(ElementType* array, int size){BucketSet bucketSet;intcapacity=10; // 桶的设置为 10.int i, j;bucketSet = initBucketSet(capacity);if(bucketSet==NULL){return ;}  for(i=1; i<=3; i++){for(j=0; j<size; j++){bucketsort(bucketSet->array, array[j], i);}bucketsToArray(bucketSet, array); // 别忘记将桶中数据copy 回数组.printArray(array, size);clearBuckets(bucketSet); // 每轮都要清理 数组式链表.}}void main(){  ElementType array[] = {110, 245, 895, 658, 321, 852, 147, 458, 469, 159, 347, 28};int size=12;printf("\n radix sort based on {110, 245, 895, 658, 321, 852, 147, 458, 469, 159, 347, 28}\n");radixsort(array, size);} 




0 0
原创粉丝点击