/* * sh.set.c: "Gospodarka zmiennymi " */ [...] /* wybralem co ciekawsze i autonomicznie napisane funkcje */ static struct varent * /*szuka wezla w drzewie AVT odpowiadajacego wzorcowi pat */ madrof(pat, vp) Char *pat; register struct varent *vp; { register struct varent *vp1; for (vp = vp->v_left; vp; vp = vp->v_right) { if (vp->v_left && (vp1 = madrof(pat, vp)) != NULL) return vp1; if (Gmatch(vp->v_name, pat)) return vp; } return vp; } struct varent * /* szuka w drzewie AVT wezla ktory w polu w_name ma wartosc nazwa */ adrof1(name, v) register Char *name; register struct varent *v; { int cmp; v = v->v_left; while (v && ((cmp = *name - *v->v_name) != 0 || (cmp = Strcmp(name, v->v_name)) != 0)) if (cmp < 0) v = v->v_left; else v = v->v_right; return v; } #ifndef lint /* * */ /* makra do robienia pojedynczej rotacji na wezle p */ # define rright(p) (\ t = (p)->v_left,\ (t)->v_parent = (p)->v_parent,\ (((p)->v_left = t->v_right) != NULL) ?\ (t->v_right->v_parent = (p)) : 0,\ (t->v_right = (p))->v_parent = t,\ (p) = t) # define rleft(p) (\ t = (p)->v_right,\ ((t)->v_parent = (p)->v_parent,\ ((p)->v_right = t->v_left) != NULL) ? \ (t->v_left->v_parent = (p)) : 0,\ (t->v_left = (p))->v_parent = t,\ (p) = t) #else static struct varent * rleft(p) struct varent *p; { return (p); } static struct varent * rright(p) struct varent *p; { return (p); } #endif /* ! lint */ /* * "Wybalansuj drzewo AVT" * F == 0 znaczy ,ze przyszlismy od lewego dziecka p * D == 1 zrobilismy kasowanie w p.p. wlozenie . */ static void balance(p, f, d) register struct varent *p; register int f, d; { register struct varent *pp; #ifndef lint register struct varent *t; #endif /* !lint */ register int ff; #ifdef lint ff = 0; #endif /* * p jest wierzchilkiem od ktorego przyszlismy i na ktorym operujemy * pp jest jego ojcem ,f jest galezia od ktorej przyszlismy ff to galaz * pp na ktorej jest p */ for (; (pp = p->v_parent) != 0; p = pp, f = ff) { ff = pp->v_right == p; if (f ^ d) { /* prawy ciezszy */ switch (p->v_bal) { case -1: /* byl lewy ciezszy */ p->v_bal = 0; break; case 0: /* wybalansowano */ p->v_bal = 1; break; case 1: /* byl juz prawy ciezszy */ switch (p->v_right->v_bal) { case 1: /* sigle rotate */ pp->v_link[ff] = rleft(p); p->v_left->v_bal = 0; p->v_bal = 0; break; case 0: /* jedno przejscie */ pp->v_link[ff] = rleft(p); p->v_left->v_bal = 1; p->v_bal = -1; break; case -1: /* dwa przejscia */ (void) rright(p->v_right); pp->v_link[ff] = rleft(p); p->v_left->v_bal = p->v_bal < 1 ? 0 : -1; p->v_right->v_bal = p->v_bal > -1 ? 0 : 1; p->v_bal = 0; break; default: break; } break; default: break; } } else { /* lewy ciezszy */ switch (p->v_bal) { case 1: /* byl prawy ciezszy */ p->v_bal = 0; break; case 0: /* zostalo wybalansowane */ p->v_bal = -1; break; case -1: /* byl juz lewy ciezszy */ switch (p->v_left->v_bal) { case -1: /* jedno przejscie */ pp->v_link[ff] = rright(p); p->v_right->v_bal = 0; p->v_bal = 0; break; case 0: /* jedno przejscie */ pp->v_link[ff] = rright(p); p->v_right->v_bal = -1; p->v_bal = 1; break; case 1: /* dwa przejscia */ (void) rleft(p->v_left); pp->v_link[ff] = rright(p); p->v_left->v_bal = p->v_bal < 1 ? 0 : -1; p->v_right->v_bal = p->v_bal > -1 ? 0 : 1; p->v_bal = 0; break; default: break; } break; default: break; } } /* * jesli ze strony wlozenia jestesmy wtedy konczymy z p * wybalansowanym ,w p.p. nie */ if ((p->v_bal == 0) ^ d) break; } } [....]