我们经常在学校学习阶段听到木桶原理这个词,意思就是说这个木桶所能装载的水的量是由最短的那个木板决定的,随着我们认知的增加,又有个新的木桶原理:如果将木桶倾斜,这个木桶所能装载水的量就是由长木板决定的。
是不是感觉被生活欺骗了,不管是啥情况好像都有个解释。就像这个不完美的通,总有各种解释来把它包装的花里胡哨。
在我们计算机领域,这个桶能用来干什么呢?
在虚拟的环境下,你想让桶装啥它就装啥,只不过我们一般用来装数据。
说到数据就不得不提到我们的排序:桶排
桶排
桶排又称为箱排,是一种要求严苛的排序。为什么严苛呢?他要求所有的桶必须一样大。但是话说会来,严苛是对人严苛,对计算机那就是再简单不过的了,计算机的理解就是数据的长度必须完全一样嘛,这个计算机很擅长干。
很多同学学完C语言冒泡选择一辈子都忘不了,比如我。但是听到桶瑟瑟发抖,这里我们先打个预防针,桶排你想让它多简单它就有多简单,但是你设计的不好,它也很复杂。
我们来看最基础的一种,拿数组实现桶排。
我们首先要考虑到桶的大小是相等的,所以我们需要将这个数组合理等分,实现起来也很好实现,直接除就能得到桶的数量。这里我们为了好理解,我们设计成最简单的模式
数据在1~9的整型数。样例:4 8 6 9 7 2 2 1 6
我们设计一个数组这个数组有样例个整型空间
我们设计一个不可能出现的数据作为这个空间(桶)的初始值。
这样我们这个桶就实现出来了,然后就是数据存放问题了。
桶排实际上完成的是个映射关系,我们这个样例中运用了最简单的映射关系,即下标为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;
else
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)实现桶的结构,但是这又怎么会难住聪明的你呢?
末尾彩蛋:如果你觉得自己不自信,看看这张图