#include #include #include "tsearch.h" static inline int height(struct node *n) { return n ? n->h : 0; } static int rot(void **p, struct node *x, int dir /* deeper side */) { struct node *y = x->a[dir]; struct node *z = y->a[!dir]; int hx = x->h; int hz = height(z); if (hz > height(y->a[dir])) { /* * x * / \ dir z * A y / \ * / \ --> x y * z D /| |\ * / \ A B C D * B C */ x->a[dir] = z->a[!dir]; y->a[!dir] = z->a[dir]; z->a[!dir] = x; z->a[dir] = y; x->h = hz; y->h = hz; z->h = hz+1; } else { /* * x y * / \ / \ * A y --> x D * / \ / \ * z D A z */ x->a[dir] = z; y->a[!dir] = x; x->h = hz+1; y->h = hz+2; z = y; } *p = z; return z->h - hx; } /* balance *p, return 0 if height is unchanged. */ int __tsearch_balance(void **p) { struct node *n = *p; int h0 = height(n->a[0]); int h1 = height(n->a[1]); if (h0 - h1 + 1u < 3u) { int old = n->h; n->h = h0

h - old; } return rot(p, n, h0key); if (!c) return n; a[i++] = &n->a[c>0]; n = n->a[c>0]; } r = malloc(sizeof *r); if (!r) return 0; r->key = key; r->a[0] = r->a[1] = 0; r->h = 1; /* insert new node, rebalance ancestors. */ *a[--i] = r; while (i && __tsearch_balance(a[--i])); return r; }