瞎掰一个效率最高的整数排序算法,bitmap排序,时间复杂度O(n)

先上结果,速度上秒掉各种排序:
1e4 Straight Insertion: 0.109916 Sec
1e4 Bitmap sorting    : 0.000214 Sec
1e8 Bitmap sorting    : 6.568575 Sec

前提条件是一般测试数据偏差不大,因此可以用bitmap来标记数据,标记完了自然就排序完成。比堆排序还要快一两个数量级。
缺点也很明显:占内存,只能使用不是特别多的数据排序。
内存评估:一字节8bit, 1M内存是8M bitmap, 1G内存可以排序偏差为8e9的数据,所以一般开发时如果内存够用可以快速出结果。上面1e8个随机数,生成的时候取值在1e9之内,所以内存占用125M.

实现:先扫描出最大最小值,然后分配bitmap内存,再扫描一次做标记,完工。复杂度应该是O(n)

参考:各种排序1万条随机数对比:https://wenku.baidu.com/view/65a02500168884868662d637.html

int *bitmap_sort(int *d, int n, int *r_min, int *r_count) {
	//first scan find min and max
	//create bitmap, size(max-min)
	//2nd scan map existance of each number
	int i;
	int min = d[0];
	int max = d[0];

	for (i = 1; i < n; ++i) {
		if (d[i] < min)
			min = d[i];
		else if (d[i] > max)
			max = d[i];
	}

	int int_bits = sizeof(int) * 8;
	*r_min = min;
	*r_count = (max - min + 1) / int_bits + 1;
	int *bitmap = (int *) calloc(int_bits, *r_count);
	for (i = 0; i < n; ++i) {
		int idx = d[i] - min;
		bitmap[idx / int_bits] |= 1 << (idx % int_bits);
	}
	return bitmap;
}

void bitmap_dump(int min, int count, int* bitmap) {
	int i, j, v;
	int idx = 0;
	for (i = 0; i < count; ++i) {
		v = bitmap[i];
		for (j = 0; j < sizeof(int) * 8; ++j) {
			if (v & (1 << j)) {
				if (idx % 50 == 49)
					printf("\n");
				printf("%d ", min + i * sizeof(int) * 8 + j);
				idx++;
			}
		}
	}
	printf("\n");
}

void bitmap_sort_test(int n, int* d) {
	clock_t start;
	int min, count;
	int* bitmap;

	if (n < 1000)
		bitmap_dump(min, count, bitmap);

	start = clock();

	bitmap = bitmap_sort(d, n, &min, &count);

	printf("Bitmap Sort total time: %f\n",
			(clock() - (double) start) / CLOCKS_PER_SEC);

	if (n < 1000)
		bitmap_dump(min, count, bitmap);
}

int main(int argc, char **argv) {
	clock_t start;
//	int d[] = { 2, 5, 9, 3, 4 };
//	int n = sizeof(d) / sizeof(d[0]);

	int n = 1e8;
	int *d = (int *) malloc(n * sizeof(int));
	if (!d) {
		printf("not enough memory\n");
		return -1;
	}

	make_random_data(d, n);

	if (n <= 1e5) {
		if (n < 1000)
			dump_data(d, n, 0);
		start = clock();
		straight_insertion_sort(d, n);
		printf("Straight Insertion total time: %f\n",
				(clock() - (double) start) / CLOCKS_PER_SEC);
		if (n < 1000)
			dump_data(d, n, 1);
	}

	bitmap_sort_test(n, d);

	return EXIT_SUCCESS;
}

猜你喜欢

转载自steeven.iteye.com/blog/2365923