lua排序函数(table.sort)报错浅析————invalid order function for sorting

文章目录

      • table.sort 概述
      • table.sort源码及注释
      • invalid order function for sorting报错的原因及解决方法
      • 个人认为较好的lua排序函数写法

table.sort 概述

  1. table.sort函数的本质是快排算法,在此基础上做了三点优化
  2. 每次分割数组的锚点是从当前分割数组的初始点、中间点、结尾点中选择中位数作为锚点,减少极端情况下快排的次数每次分割数组的锚点是从当前分割数组的初始点、中间点、结尾点中选择中位数作为锚点,减少极端情况下快排的次数
  3. 对于迭代函数中的分割数组长度小于等于3的,直接通过比较大小交换位置,形成有序数组,这样做的目的是减少递归调用的深度
  4. 每次通过锚点把分割数组分成两半之后,对长度较小的一半进行递归调用,另一半则继续通过While继续分割处理,目的应该也是减少递归调用的深度

table.sort源码及注释

    static void auxsort (lua_State *L, int l, int u) {
      while (l < u) {  /* for tail recursion */
        int i, j;
        /* sort elements a[l], a[(l+u)/2] and a[u] */
        lua_rawgeti(L, 1, l);
        lua_rawgeti(L, 1, u);
        if (sort_comp(L, -1, -2))  /* a[u] < a[l]? */
          set2(L, l, u);  /* swap a[l] - a[u] */
        else
          lua_pop(L, 2);
        if (u-l == 1) break;  /* only 2 elements */
        i = (l+u)/2;
        lua_rawgeti(L, 1, i);
        lua_rawgeti(L, 1, l);
        if (sort_comp(L, -2, -1))  /* a[i]= P */
          while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) {
            if (i>u) luaL_error(L, "invalid order function for sorting");
            lua_pop(L, 1);  /* remove a[i] */
          }
          /* repeat --j until a[j] <= P */
          while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) {
            if (j

invalid order function for sorting报错的原因及解决方法

     while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) {
         if (i>u) luaL_error(L, "invalid order function for sorting");
         lua_pop(L, 1);  /* remove a[i] */
     }
     /* repeat --j until a[j] <= P */
     while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) {
       if (j

在源码中可以看到报错的位置。当锚点的值与边界值相等,这时如果排序方法sort_comp返回true,则会造成数组越界,而解决方案也很简单——当比较的两个值相等时,返回false即可。

个人认为较好的lua排序函数写法

假设战力排行榜有战力,等级两个排序因子,要求先按战力从高往低排,再按等级从高往低排,那么排序函数可以这么写。

    table.sort(战力排行榜, function(a, b)
        if a.战力 ~= b.战力 then
            return a.战力 > b.战力
        end
        if a.等级 ~= b.等级 then
            return a.等级 > b.等级
        end
        return false
    end)

ps:上文提及lua版本是 5.1

你可能感兴趣的:(lua)