avlnode_delete.c (1776B)
1 /* ISC license. */ 2 3 #include <stdint.h> 4 5 #include <skalibs/avlnode.h> 6 #include "avlnode-internal.h" 7 8 uint32_t avlnode_delete (avlnode *s, uint32_t max, uint32_t *root, void const *k, dtok_func_ref dtok, cmp_func_ref f, void *p) 9 { 10 uint32_t r = *root ; 11 uint32_t itodel ; 12 uint32_t stack[AVLNODE_MAXDEPTH] ; 13 uint8_t spin[AVLNODE_MAXDEPTH] ; 14 uint8_t sp = 0 ; 15 16 for (; r < max ; sp++) 17 { 18 int c = (*f)(k, (*dtok)(s[r].data, p), p) ; 19 if (!c) break ; 20 spin[sp] = avlnode_ufroms(c) ; 21 stack[sp] = r ; 22 r = s[r].child[spin[sp]] ; 23 } 24 if (r >= max) return max ; 25 itodel = r ; 26 27 if ((s[r].child[0] < max) || (s[r].child[1] < max)) 28 { 29 uint8_t subspin = s[r].child[1] < max ; 30 stack[sp] = r ; 31 spin[sp++] = subspin ; 32 r = s[r].child[subspin] ; 33 for (; r < max ; sp++) 34 { 35 stack[sp] = r ; 36 spin[sp] = !subspin ; 37 r = s[r].child[!subspin] ; 38 } 39 r = stack[--sp] ; 40 s[itodel].data = s[r].data ; 41 itodel = s[r].child[subspin] ; 42 if (itodel < max) 43 { 44 s[r].data = s[itodel].data ; 45 stack[sp] = r ; 46 spin[sp++] = subspin ; 47 } 48 else itodel = r ; 49 } 50 51 r = max ; 52 while (sp--) 53 { 54 s[stack[sp]].child[spin[sp]] = r ; 55 r = stack[sp] ; 56 if (!s[r].balance) goto easyfix ; 57 else if (spin[sp] == avlnode_ufroms(s[r].balance)) s[r].balance = 0 ; 58 else if (!s[s[r].child[!spin[sp]]].balance) goto hardfix ; 59 else r = avlnode_rotate_maydouble(s, max, r, spin[sp], spin[sp] == avlnode_ufroms(s[s[r].child[!spin[sp]]].balance)) ; 60 } 61 *root = r ; 62 return itodel ; 63 64 easyfix: 65 s[r].balance = -avlnode_sfromu(spin[sp]) ; 66 return itodel ; 67 68 hardfix: 69 r = avlnode_rotate(s, max, r, spin[sp]) ; 70 if (!sp--) *root = r ; 71 else s[stack[sp]].child[spin[sp]] = r ; 72 return itodel ; 73 }