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

Defined functions

NUM defined in line 111; used 8 times
SETNUM defined in line 118; used 1 times
exits defined in line 46; used 2 times
getreach defined in line 31; used 1 times
inspr defined in line 127; used 3 times
number defined in line 92; used 3 times

Defined struct's

pair defined in line 25; used 6 times
Last modified: 1981-07-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 767
Valid CSS Valid XHTML 1.0 Strict