Annotation of 42BSD/usr.bin/struct/3.reach.c, revision 1.1

1.1     ! root        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:        }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.