在计算机科学中,排序算法是基础且重要的一环。传统的排序算法,如快速排序和堆排序,通常具有O(n log n)的时间复杂度。提出了一种可能达到O(n)复杂度的排序算法,这让感到非常好奇。
本文将探索一系列排序算法。参考了William H. Press等人所著的《Numerical Recipes in C》(1999年第二版)一书。该书的第八章详细介绍了多种排序算法,并提供了C语言的源代码和解释。
任何优秀的程序员都应掌握排序技巧。不能在不了解这一基础主题的情况下,自称为数值技术专家。
具体来说,本章将处理以下任务:
对于基本的排序N个元素的任务,最好的算法大约需要n log n次操作。算法的发明者试图将这个估计前面的常数减到尽可能小。
两种最好的算法是C.A.R. Hoare发明的“快速排序”和J.W.J. Williams发明的“堆排序”。对于大的n(比如大于1000),快速排序在大多数机器上比堆排序快1.5到2倍;然而,它需要一些额外的内存,并且程序相对复杂。堆排序是一种真正的“就地排序”,程序更紧凑,因此更容易为特殊目的进行修改。
这是对使用数字排序元素的想法的介绍。网格的特性是使用二维值进行单独排序的切割。这个想法表明,对于一个数字,有两个其他变量,方程式就是通常用于极坐标中笛卡尔坐标系的勾股定理距离。
接下来的段落将从这个想法的开始,通过一个例子进行探索,并将算法适应为真实。在本文后面,将展示这个算法,它对包含数字的n个元素进行分类。
假设想对以下数字列表进行排序:
11 62 88 30 5 45 13 70 76
可以给出这个数字列表的另一种排列。但是,这些数字只有一种排列是按升序排列的。提议用这个例子来展示帮助排序的网格。
这个网格在水平线上显示任何数字的个位数字。然后,在垂直列中,对于小于或等于99的数字,有10个可能的十位数字。
现在,为了对列表进行排序,必须从上到下,然后从左到右读取这个网格。
预测算法的过程很重要,以便可视化所有风险,并证明算法可能是真实的或有错误测试,这可能会在结果中留下错误。
网格是一个模型,用于理解一个随机数字列表简单地是一个通过相应有序列表从一开始就获得的多重排列的实例。
此外,填充一个没有重复的100个数字的列表的位置是浏览网格。如果列表包含重复的数字,重要的是计算重复数字的数量。然后,为每个重复数字的列表保持这个计数器。
使用网格存储数字并通过网格以有序迭代对它们进行排序是一个好主意。
然而,确切的算法并不完全是用于存储数字的网格。网格必须用每个数字的切割填充。列和行的乘积必须等于列表中的元素数量。
网格可以有三维或四维;但是,用二维网格,必须取最近的平方,使得列表中的元素数量等于p^2。所以对于三维网格,必须取最近的立方,使得元素数量等于p^3。
数学和代数表明,存在一个数值上等于三维网格的二维网格。有了这个断言,可以使用二维网格来存储所有要排序的列表项。但是,这可能不适用于所有列表大小。
在后一种情况下,列表简单地被分成两部分;剩余的部分可以放在网格的最后一个单元格内。
根据网格排序方法,其复杂度为O(n)。首先,列表迭代一次,所以需要n次循环。其次,有两种方式:
第一种选择要求算法的复杂度与b^2相同,其中b是列表中每个值的切割。第二种选择是实现网格的最佳方式。
当列表中有N个元素,每个元素最多有k位数字时,存在一个最优的网格维度(2、3或更多)和每个维度的基数,也称为代数中的Ker(F)。
连续数字的和是
n*(n+1)/2
当尝试在网格中定位并且有15个元素时,可以创建一个5行6列的网格。这是制作的网格:
这个方程是一个二次多项式。这个方程中的1意味着它是一个只有一个转弯的进展,对于每个新元素。如果不是1,它可能是一个数字,它通过连续的距离发出每个项,就像这样,每个项被相同的距离隔开。
最后,两个方程给出了所有元素的总和和最大的元素(由变量x标识)的距离和解决方案。
因此,该算法是迭代的。如果遇到一个正方形u,用x+u和u提供的行和列绘制网格。增量回放太昂贵了。
尽管可以计算每个项的确切位置并与其他项交换,但不能浏览列表以找到特定项及其放置位置。同样,不能将一个项插入到已排序的列表中,因为插入的项正在移动所有后续项。
在学习计算机科学时,了解到排序算法的主要需求。特别是,排序算法是真实的,直到找到一个具有特定数字列表和结果是一个无序列表的例子。这是Hoare的逻辑和Hoare证明的逻辑。
然后,当告诉一个新的排序算法时,主要的搜索是证明这个算法将始终是有序列表的结果。为此,首先花时间使用它并探索有机模型以确保它是一个真正的排序算法。