00后小哥告诉你,何谓桶排序?
我们经常在学校学习阶段听到木桶原理这个词,意思就是说这个木桶所能装载的水的量是由最短的那个木板决定的
随着我们认知的增加,又有个新的木桶原理:如果将木桶倾斜,这个木桶所能装载水的量就是由长木板决定的。
是不是感觉被生活欺骗了,不管是啥情况好像都有个解释。就像这个不完美的桶,总有各种解释来把它包装的花里胡哨。在我们计算机领域,这个桶能用来干什么呢?
在虚拟的环境下,你想让桶装啥它就装啥,只不过我们一般用来装数据。说到数据就不得不提到我们的排序:桶排
桶排
桶排又称为箱排,是一种要求严苛的排序。为什么严苛呢?他要求所有的桶必须一样大。但是话说回来,严苛是对人严苛,对计算机那就是再简单不过的了,计算机的理解就是数据的长度必须完全一样嘛,这个计算机很擅长干。
很多同学学完 C
语言冒泡选择一辈子都忘不了,比如我。但是听到桶瑟瑟发抖,这里我们先打个预防针,桶排序你想让它多简单它就有多简单,但是你设计的不好,它也很复杂。
用数组实现桶排。
首先要考虑到桶的大小是相等的,所以我们需要将这个数组合理等分,实现起来也很好实现,直接除就能得到桶的数量。为了好理解,这里设计成最简单的模式假如有 9 个数字要进行排序,他们分别是
4 8 6 9 7 2 2 1 6
先定义一个大小为 9
的一维数组,并使用未出现过的数字来填满整个空间,作为初始值。
ok, 桶有了,至于为什么是桶,关键就在于下面这段话!
桶排实际上完成的是个映射关系,我们这个样例中运用了最简单的映射关系,即下标为 K
对应的空间存放的是实际数为 K+1
的值的个数。
没想清楚怎么办,多读两遍!接下来只需要遍历数组,将关系一一映射进这个我们虚拟化的桶中。
最后我们将这个桶遍历打印就行。原理搞定!!
问题 1:给定数据出现重复怎么办?我们只需要将记录的数据空间原来的值加一就行我们来看对应的存放表
来看代码实现
void RadixSort(int *arr, int length) {
//申请桶空间
int* p = (int*)malloc(sizeof(int)*length);
//将这个桶空间初始化为不可能出现的值
memset(p, 0, length * sizeof(int));
for (int i = 0; i < length; ++i) {
p[arr[i] - 1] += 1;
}
for (int j = 0; j < length; ++j) {
if (p[j] == 0) continue;
while (p[j]) {
printf("%d ", j + 1);
p[j]--;
}
}
}
主函数
int main() {
int arr[] = {
4,8,6,9,7,2,2,1,6
};
int sz = sizeof(arr) / sizeof(arr[0]);
RadixSort(arr, sz);
return 0;
}
学到这,你已经会了最简单的桶排啦,你可以自己尝试复杂点的,桶排的复杂程度取决于设计者的设计模式,你可以设计不一样的映射关系或者不一样的数据结构(例如 list
)实现桶的结构,但是这又怎么会难住聪明的你呢?末尾彩蛋:如果你觉得自己不自信,看看这张图