Advertisement
Guest User

Untitled

a guest
Apr 17th, 2019
180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.34 KB | None | 0 0
  1. // Sorting is performed by generating the binary search tree and then
  2. // constructing the sorted array on recursive walk. Neither stage makes use of
  3. // recursive function calls. The latter one imitates it (stack, stack pointer,
  4. // instruction pointer, return instruction pointer). A node is extremely
  5. // compact, as the index of the node itself is the index of the corresponding
  6. // array element, the first and the second fields are indices of nodes, that
  7. // stand for an element, which is less, and one, which is greater,
  8. // respectively.
  9.  
  10. int *tree_mk(void *arr_, size_t num, size_t sz, int (*cmp)(void*,void*))
  11. {
  12.     char (*arr)[sz] = arr_;
  13.     int (*t)[2] = malloc(num * 2 * sizeof(int));
  14.  
  15.     t[0][0] = t[0][1] = -1;
  16.     for (int i = 1; i < num; ++i) {
  17.         t[i][0] = t[i][1] = -1;
  18.         int i_ = -1, _i = 0, j;
  19.         while (_i != -1) {
  20.             i_ = _i;
  21.             j = (cmp(&arr[i], &arr[i_]) < 0) ? 0 : 1;
  22.             _i = t[i_][j];
  23.         }
  24.         t[i_][j] = i;
  25.     }
  26.     return (int *)t;
  27. }
  28.  
  29. void tree_vec(void *dst_, void *src_, size_t sz, int (*tree)[2])
  30. {
  31.     char (*dst)[sz] = dst_, (*src)[sz] = src_;
  32.  
  33.     enum { IDX, RET };
  34.     int stack[0x1000][2];
  35.     stack[0][IDX] = stack[0][RET] = 0;
  36.  
  37.     for (int sp = 0, ip = 0; sp != -1; ++ip) {
  38.         int idx = stack[sp][IDX],
  39.             ret = stack[sp][RET];
  40.         switch (ip) {
  41.             case 0:
  42.                 if (tree[idx][0] != -1) {
  43.                     ++sp;
  44.                     stack[sp][IDX] = tree[idx][0];
  45.                     stack[sp][RET] = ip;
  46.                     ip = -1;
  47.                 }
  48.                 break;
  49.             case 1:
  50.                 memcpy(dst++, src[idx], sz);
  51.                 break;
  52.             case 2:
  53.                 if (tree[idx][1] != -1) {
  54.                     ++sp;
  55.                     stack[sp][IDX] = tree[idx][1];
  56.                     stack[sp][RET] = ip;
  57.                     ip = -1;
  58.                 }
  59.                 break;
  60.             case 3:
  61.                 --sp;
  62.                 ip = ret;
  63.                 break;
  64.         }
  65.     }
  66. }
  67.  
  68. void tsort(void *dst, size_t num, size_t sz, int (*cmp)(void*,void*))
  69. {
  70.     void *src = malloc(num * sz);
  71.     memcpy(src, dst, num * sz);
  72.  
  73.     int *tree = tree_mk(src, num, sz, cmp);
  74.     tree_vec(dst, src, sz, (int (*)[2])tree);
  75.  
  76.     free(tree);
  77.     free(src);
  78. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement