Beispiel #1
0
/*
** QuickSort algorithm (recursive function)
*/
static void auxsort (lua_State *L, IdxT lo, IdxT up,
                                   unsigned int rnd) {
  while (lo < up) {  /* loop for tail recursion */
    IdxT p;  /* Pivot index */
    IdxT n;  /* to be used later */
    /* sort elements 'lo', 'p', and 'up' */
    lua_geti(L, 1, lo);
    lua_geti(L, 1, up);
    if (sort_comp(L, -1, -2))  /* a[up] < a[lo]? */
      set2(L, lo, up);  /* swap a[lo] - a[up] */
    else
      lua_pop(L, 2);  /* remove both values */
    if (up - lo == 1)  /* only 2 elements? */
      return;  /* already sorted */
    if (up - lo < RANLIMIT || rnd == 0)  /* small interval or no randomize? */
      p = (lo + up)/2;  /* middle element is a good pivot */
    else  /* for larger intervals, it is worth a random pivot */
      p = choosePivot(lo, up, rnd);
    lua_geti(L, 1, p);
    lua_geti(L, 1, lo);
    if (sort_comp(L, -2, -1))  /* a[p] < a[lo]? */
      set2(L, p, lo);  /* swap a[p] - a[lo] */
    else {
      lua_pop(L, 1);  /* remove a[lo] */
      lua_geti(L, 1, up);
      if (sort_comp(L, -1, -2))  /* a[up] < a[p]? */
        set2(L, p, up);  /* swap a[up] - a[p] */
      else
        lua_pop(L, 2);
    }
    if (up - lo == 2)  /* only 3 elements? */
      return;  /* already sorted */
    lua_geti(L, 1, p);  /* get middle element (Pivot) */
    lua_pushvalue(L, -1);  /* push Pivot */
    lua_geti(L, 1, up - 1);  /* push a[up - 1] */
    set2(L, p, up - 1);  /* swap Pivot (a[p]) with a[up - 1] */
    p = partition(L, lo, up);
    /* a[lo .. p - 1] <= a[p] == P <= a[p + 1 .. up] */
    if (p - lo < up - p) {  /* lower interval is smaller? */
      auxsort(L, lo, p - 1, rnd);  /* call recursively for lower interval */
      n = p - lo;  /* size of smaller interval */
      lo = p + 1;  /* tail call for [p + 1 .. up] (upper interval) */
    }
    else {
      auxsort(L, p + 1, up, rnd);  /* call recursively for upper interval */
      n = up - p;  /* size of smaller interval */
      up = p - 1;  /* tail call for [lo .. p - 1]  (lower interval) */
    }
    if ((up - lo) / 128 > n) /* partition too imbalanced? */
      rnd = l_randomizePivot();  /* try a new randomization */
  }  /* tail call auxsort(L, lo, up, rnd) */
}
Beispiel #2
0
static int libE_sort (lua_State *L) {
  int n = aux_getn(L, 1);
  luaL_checkstack(L, 40, "");  /* assume array is smaller than 2^40 */
  if (!lua_isnoneornil(L, 2))  /* is there a 2nd argument? */
    luaL_checktype(L, 2, LUA_TFUNCTION);
  lua_settop(L, 2);  /* make sure there is two arguments */
  auxsort(L, 1, n);
  return 0;
}
Beispiel #3
0
static int sort (killa_State *L) {
  int n = aux_getn(L, 1) + KILLA_BASE - 1;
  killaL_checkstack(L, 40, "");  /* assume array is smaller than 2^40 */
  if (!killa_isnoneornull(L, 2))  /* is there a 2nd argument? */
    killaL_checktype(L, 2, KILLA_TFUNCTION);
  killa_settop(L, 2);  /* make sure there is two arguments */
  auxsort(L, KILLA_BASE, n);
  return 0;
}
static int sort (lua_State *L) {
  TabA ta;
  int n = (int)aux_getn(L, 1, &ta);
  luaL_checkstack(L, 50, "");  /* assume array is smaller than 2^50 */
  if (!lua_isnoneornil(L, 2))  /* is there a 2nd argument? */
    luaL_checktype(L, 2, LUA_TFUNCTION);
  lua_settop(L, 2);  /* make sure there are two arguments */
  auxsort(L, &ta, 1, n);
  return 0;
}
Beispiel #5
0
static int luaB_sort (lua_State *L) {
  int n;
  luaL_checktype(L, 1, LUA_TTABLE);
  n = lua_getn(L, 1);
  if (!lua_isnull(L, 2))  /* is there a 2nd argument? */
    luaL_checktype(L, 2, LUA_TFUNCTION);
  lua_settop(L, 2);  /* make sure there is two arguments */
  auxsort(L, 1, n);
  return 0;
}
Beispiel #6
0
static int sort (lv_State *L) {
    lv_clearFirstTableValue(L);
    int n = aux_getn(L, 1);
    lvL_checkstack(L, 40, "");  /* assume array is smaller than 2^40 */
    if (!lv_isnoneornil(L, 2))  /* is there a 2nd argument? */
        lvL_checktype(L, 2, LV_TFUNCTION);
    lv_settop(L, 2);  /* make sure there is two arguments */
    auxsort(L, 1, n);
    return 0;
}
Beispiel #7
0
static int sort (lua_State *L) {
  lua_Integer n = aux_getn(L, 1, TAB_RW);
  if (n > 1) {  /* non-trivial interval? */
    luaL_argcheck(L, n < INT_MAX, 1, "array too big");
    if (!lua_isnoneornil(L, 2))  /* is there a 2nd argument? */
      luaL_checktype(L, 2, LUA_TFUNCTION);  /* must be a function */
    lua_settop(L, 2);  /* make sure there are two arguments */
    auxsort(L, 1, (IdxT)n, 0);
  }
  return 0;
}
Beispiel #8
0
static void luaB_sort (void) {
  lua_Object t = lua_getparam(1);
  Hash *a = gethash(1);
  int n = (int)getnarg(a);
  lua_Object func = lua_getparam(2);
  luaL_arg_check(func == LUA_NOOBJECT || lua_isfunction(func), 2,
                 "function expected");
  luaD_checkstack(4);  /* for Pivot, f, a, b (sort_comp) */
  auxsort(a, 1, n, func);
  lua_pushobject(t);
}
Beispiel #9
0
LUACLLIB_API void luaC_sortlist(lua_State* L, int tabix, int funcix /*=0*/)
{
	luaL_checkstack(L, 41, "");
	luaL_checktype(L, tabix, LUA_TTABLE);
	int t = lua_gettop(L);
	int ix = tabix; if (ix < 0) ix = t + (ix + 1);
	if (funcix == 0)
		lua_pushnil(L);
	else
		lua_pushvalue(L, funcix);
	int n = aux_getn(L, ix);
	auxsort(L, 1, n, ix, t + 1);
	lua_settop(L, t);
}
Beispiel #10
0
static void auxsort (Hash *a, int l, int u, lua_Object f) {
  while (l < u) {  /* for tail recursion */
    TObject *P;
    int i, j;
    /* sort elements a[l], a[(l+u)/2] and a[u] */
    if (sort_comp(f, luaH_getint(a, u), luaH_getint(a, l)))  /* a[l]>a[u]? */
      swap(a, l, u);
    if (u-l == 1) break;  /* only 2 elements */
    i = (l+u)/2;
    P = luaH_getint(a, i);
    if (sort_comp(f, P, luaH_getint(a, l)))  /* a[l]>a[i]? */
      swap(a, l, i);
    else if (sort_comp(f, luaH_getint(a, u), P))  /* a[i]>a[u]? */
      swap(a, i, u);
    if (u-l == 2) break;  /* only 3 elements */
    P = L->stack.top++;
    *P = *luaH_getint(a, i);  /* save pivot on stack (for GC) */
    swap(a, i, u-1);  /* put median element as pivot (a[u-1]) */
    /* a[l] <= P == a[u-1] <= a[u], only needs to sort from l+1 to u-2 */
    i = l; j = u-1;
    for  (;;) {
      /* invariant: a[l..i] <= P <= a[j..u] */
      while (sort_comp(f, luaH_getint(a, ++i), P))  /* stop when a[i] >= P */
        if (i>u) lua_error("invalid order function for sorting");
      while (sort_comp(f, P, luaH_getint(a, --j)))  /* stop when a[j] <= P */
        if (j<l) lua_error("invalid order function for sorting");
      if (j<i) break;
      swap(a, i, j);
    }
    swap(a, u-1, i);  /* swap pivot (a[u-1]) with a[i] */
    L->stack.top--;  /* remove pivot from stack */
    /* a[l..i-1] <= a[i] == P <= a[i+1..u] */
    /* adjust so that smaller "half" is in [j..i] and larger one in [l..u] */
    if (i-l < u-i) {
      j=l; i=i-1; l=i+2;
    }
    else {
      j=i+1; i=u; u=j-2;
    }
    auxsort(a, j, i, f);  /* call recursively the smaller one */
  }  /* repeat the routine for the larger one */
}
static void auxsort (lua_State *L, TabA *ta, int l, int u) {
  while (l < u) {  /* for tail recursion */
    int i, j;
    /* sort elements a[l], a[(l+u)/2] and a[u] */
    (*ta->geti)(L, 1, l);
    (*ta->geti)(L, 1, u);
    if (sort_comp(L, -1, -2))  /* a[u] < a[l]? */
      set2(L, ta, l, u);  /* swap a[l] - a[u] */
    else
      lua_pop(L, 2);
    if (u-l == 1) break;  /* only 2 elements */
    i = (l+u)/2;
    (*ta->geti)(L, 1, i);
    (*ta->geti)(L, 1, l);
    if (sort_comp(L, -2, -1))  /* a[i]<a[l]? */
      set2(L, ta, i, l);
    else {
      lua_pop(L, 1);  /* remove a[l] */
      (*ta->geti)(L, 1, u);
      if (sort_comp(L, -1, -2))  /* a[u]<a[i]? */
        set2(L, ta, i, u);
      else
        lua_pop(L, 2);
    }
    if (u-l == 2) break;  /* only 3 elements */
    (*ta->geti)(L, 1, i);  /* Pivot */
    lua_pushvalue(L, -1);
    (*ta->geti)(L, 1, u-1);
    set2(L, ta, i, u-1);
    /* a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */
    i = l; j = u-1;
    for (;;) {  /* invariant: a[l..i] <= P <= a[j..u] */
      /* repeat ++i until a[i] >= P */
      while ((*ta->geti)(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 ((*ta->geti)(L, 1, --j), sort_comp(L, -3, -1)) {
        if (j<=l) luaL_error(L, "invalid order function for sorting");
        lua_pop(L, 1);  /* remove a[j] */
      }
      if (j<i) {
        lua_pop(L, 3);  /* pop pivot, a[i], a[j] */
        break;
      }
      set2(L, ta, i, j);
    }
    (*ta->geti)(L, 1, u-1);
    (*ta->geti)(L, 1, i);
    set2(L, ta, u-1, i);  /* swap pivot (a[u-1]) with a[i] */
    /* a[l..i-1] <= a[i] == P <= a[i+1..u] */
    /* adjust so that smaller half is in [j..i] and larger one in [l..u] */
    if (i-l < u-i) {
      j=l; i=i-1; l=i+2;
    }
    else {
      j=i+1; i=u; u=j-2;
    }
    auxsort(L, ta, j, i);  /* call recursively the smaller one */
  }  /* repeat the routine for the larger one */
}