计数排序中的循环解释

Loop Explanation in Counting Sort

本文关键字:循环 解释 排序      更新时间:2023-10-16

谁能给我解释一下这个计数排序实现中的第二个循环的目的?:

short c[RADIX_MAX] = {0};
int i;
for (i = 0; i < LEN_MAX; i++) {
    if (i == len)
        break;
    int ind = a.getElem(i); 
    c[ind]++;
}
for (i = 1; i < RADIX_MAX; i++) {
    if (i == radix)
        break;
    c[i] += c[i - 1];
}
for (i = LEN_MAX - 1; i >= 0; i--) {
    int j = i - LEN_MAX + len;      
    if (j < 0)
        break;
    int ind = a.getElem(j);
    short t = ind;
    ind = --c[ind];
    b.setElem(ind, t);
}

计数排序通过从元素本身的值计算要排序的每个元素的目标索引来工作。这里涉及到三次传递:

  • 在第一个循环中,对每个元素进行计数:例如,我们的数组有6个"A"、2个"B"、5个"C"等等。

  • 在第二个循环中,计算每个元素所在的索引。如果有6个"A",那么第一个"B"需要位于索引6处(在基于0的索引中)。为了使代码更简单和排序更稳定,计数排序所做的事情有点复杂。在第三个循环中,它将以反向顺序遍历原始数组,因此在第二个循环中,它不是计算给定值的第一个实例的索引,而是计算最后一个实例的索引。在上面的例子中,最后一个"A"需要出现在索引5,但是最后一个"B"需要出现在索引6("A")+ 2("B")- 1(从零开始)=索引7。因此,对于每个值,它计算该值的结束索引。它向前遍历计数数组,将先前计算的计数添加到当前计数中。所以在我们的count数组中,A的值仍然是6(没有前一个元素),B的值是6+2=8(6个A +2个B), C的值是6+2+5=13(6个A +2个B +5个C),以此类推

  • 在最后一个循环中,值被插入到它们的位置,随着我们的进行,索引递减。所以最后一个B被插入到索引7处,再前面一个被插入到索引6处,以此类推。这保留了相等元素的原始顺序,使得排序稳定,这对于基数排序是必不可少的。

对于每一个数字,我们计算它在排序数组中的起始位置。例子:
array: 0 0 0 0 2 2 3 3 3 9 9
index: 0 1 2 3 4 5 6 7 8 9 10
然后c [0] = 0, c [1] = 4, c [2] = 4, c [3] = 6, c[4] = 9,……C[9] = 9。
排序数组中数字出现的索引取决于前一位数字的索引和前一位数字的个数。第二个循环计算这个。