c 中sort对二维数组排序是不是一定要用vector

上次整理书架时,我发现按作者姓名排序比按出版年份排序更直观。
这让我想起了一些关于C中数组排序的事情。

比如有一个二维数组score[5 ][3 ],存储的是学生成绩,我想按照总分降序排序。
直接转成一维数组就可以了。
将score[i][j]更改为score[i3 +j],然后使用从score[0]到score[1 4 ]的排序。
排序后按i3 +j返回。
我记得有一次尝试使用这种方法对 1 00 行 5 列的数据进行排序。
转换为一维时,有 5 00 个元素。
排序只用了0.3 秒就完成了。
虽然最后我必须手动将一维结果填充回二维数组,但这很容易。

或者你可以编写自己的比较函数。
例如,要按第 2 列排序,比较函数将为 boolcompare(int a[], int b[]) { return a[1 ] > b[1 ]; },然后排序(&result[0][0], &result[5 ][0], 比较)。
上次给同学安排座位的时候用过。
我写了一个根据高度从高到低的比较函数,很快就完成了。

当然用vector>更简单,直接sort(v.begin(), v.end(), Compare)就可以了,不用担心内部细节。
但有时你只想使用通用数组,例如,一些较旧的系统有严格的内存限制。
我记得有一次,当我在嵌入表上运行代码时,使用向量时发生了堆栈溢出。
最后我用二维数组+自定义比较函数解决了这个问题。

等等,还有一件事。
使用数组签名进行直接比较也是可行的。
例如, for(i=0;i<5 for(j=i+1>上次我对一个只有1 0行的小数据集进行排序,这个方法可以在0.1 秒内完成,但是如果我对1 0000行进行排序...
我突然想到,如果二维数组的行和列不固定怎么办?例如,如果每次的数据量不同,则不会建立映射关系。
此时向量或动态分配的数组可能比固定大小的数组更合适?

计数排序

上周我在小组讨论中听到了如何计算算法的解释。
这个算法很有趣。

当我第一次接触2 02 3 手数算法时,我发现它是一种不依赖比较的计数算法,适合对有限的整数进行排序。

朋友说计数排序的核心是通过统计元素出现的次数来确定位置。

比如他说统计频率的步骤是帮助数组C记住数组A的每个元素出现了多少次。

然后我朋友说把介词的和转换成数组C的形式的前缀,意思是元素个数小于等于当前元素。

反向饱和是关键。
A从后向前跑,确定元素在B坐标序列中的位置,在C坐标中,并调整C坐标以建立稳定。

说明在初始化过程中,数组C的大小由取值范围决定。
例如,如果最大值为 2 5 6 ,则 C 数组有 2 5 6 个元素。

在统计阶段,他让我想象他通过了A,并统计每个值出现的次数。

总计算的前缀为C[i] += C[i-1 ],从而终止每个元素最后一个位置的扩展。

反向填充举了个例子,从A的末尾开始,将元素放置在B的所需位置,减少C的值来处理重复元素。

我问稳定性是如何建立的,他说稳定性的定义是相等元素排序后相对顺序保持不变。
计数类型的稳定性就是从A来回移动到C的值,使得相同的元素被放置在原来的B行中。

他提到了优化和变异,说如果不需要稳定性,可以直接改成A,但是给定的时间需要额外的空间。

他还补充了选择类型的稳定性,称在内存中第一个位置的稳定性可以在选择模式中做出,但会增加空间的复杂性。

对于复杂度来说,复杂度时间为 O(n+k),其中 k 是范围值。
复杂度空间也是O(n+k),C和B相加。

他举了最后一个例子,取A=[4 ,2 ,2 ,8 ,3 ],MAX=9 ,计算数组C,计算前缀之和,填充倒数数组B。

最终B=[2 ,2 ,3 ,4 ,8 ]。

我说过这个算法对于排序小范围整数非常有效。

然后他总结说,计算中利用统计量和前缀来高效定位元素的位置,适合小范围的积分排序。
稳定性来自于遍历对策和动态调整计数顺序。
优化空间复杂度需要牺牲稳定性或增加存储时间。
朋友说完这句话,我们就结束了讨论,继续各自的工作。
算了,你瞧。