Foundation: Distribution Counting Sort

来源:互联网 发布:windows phone 8.1软件 编辑:程序博客网 时间:2024/05/21 08:00
#include "distribution_counting.h"/* [Distribution Counting Sort]  * First used with radix sorting by H.Seward, 1954. * Then published with "Mathsort" by W.Feurzeig, CACM 3 (1960), 601 */static int *counting_table = NULL;static int cur_table_len = 0;static intcreate_counting_table(int cnt){F_S();counting_table = (int*)malloc(sizeof(int) * cnt);if(counting_table == NULL) {debug("malloc failed. [%s] \r\n", __FUNCTION__);return 0;}cur_table_len = cnt;F_E();return 1;}voidfree_counting_table(void){F_S();if (counting_table == NULL) return;free(counting_table);counting_table = NULL;cur_table_len = 0;F_E();}/* we guess all the items located in [@min, @max], * and do the counting for sorting. */int* do_distribution_counting_sort(void* src, int src_sz, int item_cnt, int min, int max, void *out,   GET_ITEM_FUNC get_item, SET_ITEM_FUNC set_item){int rt;int i,j;char *li,*ri;long ki;F_S();if (src == NULL || src_sz <= 0 || item_cnt <= 0) return NULL;if (min < 0 || max <= 0 || min > max) return NULL;/* try create auxiliary table for counting */if (counting_table == NULL) {        rt = create_counting_table(max+1);if (!rt) return NULL;}else {if (max > cur_table_len) {free_counting_table();rt = create_counting_table(max+1);if (!rt) return NULL;}}/* clear auxiliary table as boundary */for (i = min; i <= max; ++i) counting_table[i] = 0;/* loop and increase */for (i = 0, li = (char*)src; i < item_cnt; ++i, li += src_sz) {ki = get_item(li);if (ki < 0) {debug("Tip: do not support nagative number.\r\n");return NULL;}if (ki < min) {debug("Tip: the minimal counting boundary is too big.\r\n");return NULL;}if (ki >= max) {debug("Tip: not malloced enough aux table. \r\n");return NULL;}counting_table[ki]++;}/* accumulate */for (j = min+1; j <= max; ++j) counting_table[j] += counting_table[j-1];/* loop and output */for (i = 0, li = (char*)src; i < item_cnt; ++i, li += src_sz) {ki = get_item(li);j = --counting_table[ki];ri = (char*)out + j * src_sz;set_item(ri,ki);}F_E();return counting_table;}#ifdef DISTRIBUTION_COUNTING_SORT_DEBUGlongget_int_item(void *src){return (long)*(int*)src;}voidset_int_item(void *src, long val){*(int*)src = (int)val;}longget_char_item(void *src){return (long)*(char*)src;}voidset_char_item(void *src, long val){*(char*)src = (char)val;}intmain(int argc, char* argv[]){int i,j,k;int cnt;int* counting_table;int min,max;const int int_items[16] = { 503, 87, 512, 61, 908, 170, 897, 275,                         653, 426, 154, 509, 612, 677, 765, 703                          };char *char_items = "hello world";int out[16];char char_out[16];min = 80;max = 512;debug("[Testing distribution counting sort].. \r\n");cnt = sizeof(int_items)/sizeof(int_items[0]);debug("src database:\r\n----\r\n");for (i = 0; i < cnt; ++i) {debug("%d ", int_items[i]);}debug("\r\n----\r\n");counting_table = do_distribution_counting_sort((void*)int_items, sizeof(int), cnt, min, max, out,get_int_item, set_int_item);if (counting_table == NULL) {min = 0;max = 1024;counting_table = do_distribution_counting_sort((void*)int_items, sizeof(int), cnt, min, max, out,get_int_item, set_int_item);if (counting_table == NULL) {debug("do comparison counting sor failed. \r\n");goto END;}}debug("dst database:\r\n----\r\n");for (i = 0; i < cnt; ++i) {debug("%d ", out[i]);}debug("\r\n----\r\n");debug("\r\n");min = 0;max = 256;debug("[Testing distribution counting sort].. \r\n");cnt = strlen(char_items);debug("src database:\r\n----\r\n");for (i = 0; i < cnt; ++i) {debug("%c ", char_items[i]);}debug("\r\n----\r\n");counting_table = do_distribution_counting_sort((void*)char_items, sizeof(char), cnt, min, max, char_out,get_char_item, set_char_item);if (counting_table == NULL) {debug("do comparison counting sor failed. \r\n");goto END;}debug("dst database:\r\n----\r\n");for (i = 0; i < cnt; ++i) {debug("%c ", char_out[i]);}debug("\r\n----\r\n");debug("\r\n");free_counting_table();debug("[Testing distribution counting sort]..done. \r\n");END:while(1);return 0;}#endif /* DISTRIBUTION_COUNTING_SORT_DEBUG */

#ifndef __DISTRIBUTION_COUNTING_H__#define __DISTRIBUTION_COUNTING_H__#define DISTRIBUTION_COUNTING_SORT_DEBUGtypedef long(*GET_ITEM_FUNC)(void*);typedef void(*SET_ITEM_FUNC)(void*,long);/* we guess all the items located in [@min, @max], * and do the counting for sorting. */int* do_distribution_counting_sort(void* src, int src_sz, int item_cnt, int min, int max, void *out, GET_ITEM_FUNC get_item, SET_ITEM_FUNC set_item);void free_counting_table(void);#endif /* __DISTRIBUTION_COUNTING_H__ */
#include <stdio.h>#include <tchar.h>#include <stdlib.h>#include <malloc.h>#include <string.h>#include <math.h>#define MY_DEBUG#ifdef MY_DEBUG#define debug printf#else#define debug(x,argc, __VA_ARGS__);#endif /* MY_DEBUG */#define F_S() debug("[%s]..\r\n", __FUNCTION__)#define F_E() debug("[%s]..done. \r\n", __FUNCTION__)


Mars

Sep 8th, 2013

Any to share, e-me: mars.fu@foxmail.com

原创粉丝点击