Foundation: Comparison Counting Sort

本文探讨了排序算法中的基数计数排序方法,深入解析其原理和应用,适合对基础算法感兴趣的读者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#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 int
create_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;
}

void
free_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_DEBUG

long
get_int_item(void *src)
{
	return (long)*(int*)src;
}

void
set_int_item(void *src, long val)
{
	*(int*)src = (int)val;
}

long
get_char_item(void *src)
{
	return (long)*(char*)src;
}

void
set_char_item(void *src, long val)
{
	*(char*)src = (char)val;
}

int
main(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 /* COMPARISON_COUNTING_SORT_DEBUG */
#ifndef __COMPARISON_COUNTING_SORT_H__
#define __COMPARISON_COUNTING_SORT_H__

#define COMPARISON_COUNTING_SORT_DEBUG

#define MAX_TABLE_LEN 1024

typedef int(*cmp_func)(void*,void*);

int* do_cmp_counting_sort(void* src, int src_sz, int n, cmp_func cmp);

#endif /* __COMPARISON_COUNTING_SORT_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

### 回答1: 指针和整数之间的比较是一种常见的操作。指针是一个变量,它存储了一个内存地址,而整数是一个数值类型的变量。在C语言中,可以使用指针和整数进行比较,但需要注意一些细节。 首先,指针和整数之间的比较只有在指针指向的内存地址是有效的情况下才有意义。如果指针指向的内存地址无效,比较的结果可能是不确定的。 其次,指针和整数之间的比较是基于指针的地址值和整数的数值大小进行的。如果指针的地址值小于整数的数值,比较的结果为真;如果指针的地址值大于整数的数值,比较的结果为假。 最后,需要注意的是,在进行指针和整数之间的比较时,应该使用适当的类型转换。例如,可以将指针转换为整数类型,或将整数转换为指针类型。但是,需要确保转换是安全的,并且不会导致未定义的行为。 ### 回答2: 在C/C++编程中,当我们使用指针和整数进行比较时,就会出现"warning: comparison between pointer and integer"(指针和整数之间的比较)的警告信息。这个警告信息出现的原因是由于指针和整数之间是无法进行直接的比较的,因为它们是完全不同的数据类型。 指针是一个内存地址,通常用来指向另一个变量或数据结构中的特定位置,而整数则是一种基本数据类型,用来表示数字。在大多数情况下,指针变量独立于整数变量,它们之间通常不需要比较。然而,在一些特定的情况下,我们需要将指针转换成整数类型,或者将整数转换成指针类型才能进行比较。 例如,当我们需要在内存中定位某个特定的数据结构时,就需要将指针转换成整数类型。可以使用(void*)类型的指针进行类型转换。 在32位系统中这个类型通常是ATL那么在64位系统中这个类型通常是操作系统API的一个intPTR_t。另外也可以使用intptr_t、uintptr_t和std::intptr_t等类型。 需要注意的是,将指针转换成整数类型时,可能会有数据截断的问题,因为指针类型通常比整数类型要大。因此,在将指针转换成整数时,需要确保整数类型足够大来容纳指针类型。另外,在将整数转换成指针时,也需要注意指针的类型和内存对齐等问题,避免发生访问非法内存的错误。 综上所述,当我们在C/C++编程中遇到"warning: comparison between pointer and integer"的警告信息时,需要仔细检查代码逻辑,确保指针和整数之间的比较是合法和正确的,避免程序出现内存访问异常等问题。 ### 回答3: warning: comparison between pointer and integer是C或C++程序中常见的警告信息,它通常出现在比较指针类型和整型数据类型时,指针类型常用于存储某个对象的地址,而整型数据类型则用于存储整数值。指针类型变量的值是内存地址,而整型变量的值是整数。这两种类型是不同的,不能直接进行比较操作。 当程序执行到这里的语句时,编译器会发出“warning: comparison between pointer and integer”的警告信息,这意味着程序有可能会产生错误。比如我们常见的以下几种情况: 1.比较指针变量和整型变量 例如: int* p; int i = 10; if (p == i) { … } 这样写是错误的,因为指针类型的变量和整型类型的变量不能直接比较。正确的做法是用指针变量和指针变量比较,或者把整数转换为指针类型。 2.把整型变量赋值给指针变量 例如: int* p; int i = 10; p = i; 这样写同样是错误的,因为指针类型的变量存储的是内存地址,不能把整数直接赋值给指针变量。正确的做法是将整数转换为指针类型,如下所示: p = (int*)i; 3.比较两个不同类型的指针变量 例如: int* p1; float* p2; if (p1 == p2) { … } 这样写同样是错误的,因为不同类型的指针变量的内存地址是不同的,所以它们也不能直接比较。正确的做法是将它们转换为相同的类型后再进行比较。 总之,warning: comparison between pointer and integer是常见的程序错误。在编写代码时,我们要仔细检查语句中使用的变量类型,避免这种类型的错误。同时,开启编译器的警告选项可以及早发现这类问题,并及时进行解决。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值