1: #ifndef lint
2: static char sccsid[] = "@(#)3.reach.c 4.1 (Berkeley) 2/11/83";
3: #endif not lint
4:
5: #include <stdio.h>
6: #
7: /*
8: set REACH[v] = w if w is only node outside subtree of v which is reached from within
9: subtree of v, REACH[v] = UNDEFINED otherwise
10: */
11: #include "def.h"
12:
13: /* strategy in obtaining REACH(v) for each node v:
14: Since only need to know whether there is exactly one exit from subtree of v,
15: need keep track only of 2 farthest exits from each subtree rather than all exits.
16: The first may be the unique exit, while the second is used when the children
17: of a node has the same first exit.
18: To obtain 2 farthest exits of v, look at 2 farthest exits of children of v and
19: the nodes entered by arcs from v. Farthest exits are identified by numbering
20: the nodes from -2 to -(accessnum-2) starting at the bottom left corner of tree
21: using procedure number(). The farthest exit from the subtree of v is the one
22: with the least number according NUM to this numbering. If a node w is an exit from the
23: subtree of v, then NUM(w) < NUM(v). The negative numbers allow NUM(v) to be stored
24: in the same location as REACH(v). REACH(w) may already be set when an arc (v,w) to a child
25: is searched, but the negative numbering is consistent, i.e. NUM(v) < NUM(w) in this case
26: as in other cases where w is not an exit from the subtree of v.
27: */
28:
29: struct pair {
30: int smallest;
31: int second;
32: };
33:
34:
35: getreach() /* obtain REACH(v) for each node v */
36: {
37: VERT v;
38: struct pair *pr;
39: for (v = 0; v < nodenum; ++v)
40: REACH(v) = UNDEFINED;
41: number(START);
42: for (v = START; DEFINED(v); v = RSIB(v))
43: {
44: pr = exits(v); /* need to free the space for pr */
45: chfree(pr,sizeof(*pr));
46: }
47: }
48:
49:
50: exits(v) /* set REACH(v) = w if w is only node outside subtree of v which is reached from within
51: subtree of v, leave REACH(v) UNDEFINED otherwise */
52: VERT v;
53: {
54: struct pair *vpair, *chpair;
55: VERT w,t;
56: int i;
57: vpair = challoc(sizeof(*vpair));
58: vpair ->smallest = vpair ->second = UNDEFINED;
59: for (i = 0; i < CHILDNUM(v); ++i)
60: {
61: w = LCHILD(v,i);
62: if (!DEFINED(w)) continue;
63: for (t = w; DEFINED(t); t = RSIB(t))
64: {
65: chpair = exits(t);
66:
67: /* set vpair->smallest,second to two smallest of vpair->smallest,second,
68: chpair->smallest,second */
69: if (inspr(chpair->smallest,vpair))
70: inspr(chpair->second,vpair);
71: chfree(chpair, sizeof(*chpair));
72: }
73: }
74: for (i = 0; i < ARCNUM(v); ++i)
75: {
76: w = ARC(v,i);
77: if (!DEFINED(w)) continue;
78: inspr(w,vpair);
79: }
80: /* throw out nodes in subtree of v */
81: if (NUM(vpair->second) >= NUM(v))
82: {
83: vpair->second = UNDEFINED;
84: if (NUM(vpair->smallest) >= NUM(v))
85: vpair->smallest = UNDEFINED;
86: }
87: if (vpair->second == UNDEFINED)
88: REACH(v) = vpair->smallest; /* vpair->smallest possibly UNDEFINED */
89: else
90: REACH(v) = UNDEFINED;
91: return(vpair);
92: }
93:
94:
95: /* number nodes from -2 to -(accessnum+2) starting at bottom left corner of tree */
96: number(v)
97: VERT v;
98: {
99: int i;
100: VERT w;
101: static int count;
102: for (i = 0; i < CHILDNUM(v); ++i)
103: {
104: w = LCHILD(v,i);
105: if (DEFINED(w))
106: number(w);
107: }
108: SETNUM(v,count-2);
109: --count;
110: if (DEFINED(RSIB(v)))
111: number(RSIB(v));
112: }
113:
114:
115: NUM(v)
116: VERT v;
117: {
118: if (!DEFINED(v)) return(UNDEFINED);
119: return(REACH(v));
120: }
121:
122: SETNUM(v,count)
123: VERT v; int count;
124: {
125: /* this reuses REACH to save space;
126: /* appears to be no conflict with setting true value of REACH later */
127: REACH(v) = count;
128: }
129:
130:
131: LOGICAL inspr(w,pr) /* insert w in order in pr, return TRUE if <= smaller of pr */
132: /* don't insert duplicates */
133: VERT w;
134: struct pair *pr;
135: {
136: if (w == pr-> smallest) return(TRUE);
137: if (NUM(w) < NUM(pr->smallest))
138: {
139: pr->second = pr->smallest;
140: pr->smallest = w;
141: return(TRUE);
142: }
143: if (w == pr->second) return(FALSE);
144: if (NUM(w) < NUM(pr->second))
145: pr->second = w;
146: return(FALSE);
147: }
Defined functions
NUM
defined in line
115; used 8 times
exits
defined in line
50; used 2 times
Defined variables
sccsid
defined in line
2;
never used
Defined struct's
pair
defined in line
29; used 6 times