最近项目中用到了table.sort,发现在某些情况下自定义的排序函数中会报nil的错误,理论上对table中元素排序是不可能出现nil的。有个同事找到了一篇文章,讲的是lua的快排有个默认规则。在自定义排序函数中,当排序条件都相同的情况下必须返回false,否则就可能访问越界造成nil。
后来处于好奇我去看了下源码,确实是有这样的规则。但是原来学习C++的时候也写过快排的例子,并没有这种规则限制,写return a<=b排序结果也是完全正确的,为啥lua要加这个限制呢?网上有人说stl中也有这样的限制,我就更好奇了,于是查了下具体原因。这里涉及到了离散数学中的偏序关系。偏序关系分两类,非严格偏序和严格偏序。而lua中的table.sort要求table中的元素满足严格偏序。通俗来讲,可以认为<=或者>=是非严格偏序,<或者>是严格偏序。理论解释是什么呢?
(以来内容来自百度百科)
非严格偏序(自反偏序)的定义如下:
给定集合S,“≤”是S上的二元关系,若“≤”满足:
自反性:∀a∈S,有a≤a;
反对称性:∀a,b∈S,a≤b且b≤a,则a=b;
传递性:∀a,b,c∈S,a≤b且b≤c,则a≤c;
则称“≤”是S上的非严格偏序或自反偏序。
严格偏序(反自反偏序)的定义如下
给定集合S,“<”是S上的二元关系,若“<”满足:
反自反性:∀a∈S,有a≮a;
非对称性:∀a,b∈S,a<b ⇒ b≮a;
传递性:∀a,b,c∈S,a<b且b<c,则a<c;
则称“<”是S上的严格偏序或反自反偏序。
严格偏序与有向无环图(dag)有直接的对应关系。一个集合上的严格偏序的关系图就是一个有向无环图。其传递闭包是它自己。
至此,我可以认为lua库或者stl库有严格偏序的要求是因为要满足数学理论的严谨性。根本原因到底是不是这个其实我也没有定论。不按严格偏序会出现排序错误的情况吗?好像也举不出反例啊?难道又跟元素中存在NaN有关?请知道的小伙伴给我留言。