/*
* 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;
}
}
[....]