/* ========================================================================= */1/* === AMD_postorder ======================================================= */2/* ========================================================================= */34/* ------------------------------------------------------------------------- */5/* AMD Version 1.1 (Jan. 21, 2004), Copyright (c) 2004 by Timothy A. Davis, */6/* Patrick R. Amestoy, and Iain S. Duff. See ../README for License. */7/* email: [email protected] CISE Department, Univ. of Florida. */8/* web: http://www.cise.ufl.edu/research/sparse/amd */9/* ------------------------------------------------------------------------- */1011/* Perform a postordering (via depth-first search) of an assembly tree. */1213#include "amd_internal.h"1415GLOBAL void AMD_postorder16(17/* inputs, not modified on output: */18Int nn, /* nodes are in the range 0..nn-1 */19Int Parent [ ], /* Parent [j] is the parent of j, or EMPTY if root */20Int Nv [ ], /* Nv [j] > 0 number of pivots represented by node j,21* or zero if j is not a node. */22Int Fsize [ ], /* Fsize [j]: size of node j */2324/* output, not defined on input: */25Int Order [ ], /* output post-order */2627/* workspaces of size nn: */28Int Child [ ],29Int Sibling [ ],30Int Stack [ ]31)32{33Int i, j, k, parent, frsize, f, fprev, maxfrsize, bigfprev, bigf, fnext ;3435for (j = 0 ; j < nn ; j++)36{37Child [j] = EMPTY ;38Sibling [j] = EMPTY ;39}4041/* --------------------------------------------------------------------- */42/* place the children in link lists - bigger elements tend to be last */43/* --------------------------------------------------------------------- */4445for (j = nn-1 ; j >= 0 ; j--)46{47if (Nv [j] > 0)48{49/* this is an element */50parent = Parent [j] ;51if (parent != EMPTY)52{53/* place the element in link list of the children its parent */54/* bigger elements will tend to be at the end of the list */55Sibling [j] = Child [parent] ;56Child [parent] = j ;57}58}59}6061#ifndef NDEBUG62{63Int nels, ff, nchild ;64AMD_DEBUG1 (("\n\n================================ AMD_postorder:\n"));65nels = 0 ;66for (j = 0 ; j < nn ; j++)67{68if (Nv [j] > 0)69{70AMD_DEBUG1 (( ""ID" : nels "ID" npiv "ID" size "ID71" parent "ID" maxfr "ID"\n", j, nels,72Nv [j], Fsize [j], Parent [j], Fsize [j])) ;73/* this is an element */74/* dump the link list of children */75nchild = 0 ;76AMD_DEBUG1 ((" Children: ")) ;77for (ff = Child [j] ; ff != EMPTY ; ff = Sibling [ff])78{79AMD_DEBUG1 ((ID" ", ff)) ;80ASSERT (Parent [ff] == j) ;81nchild++ ;82ASSERT (nchild < nn) ;83}84AMD_DEBUG1 (("\n")) ;85parent = Parent [j] ;86if (parent != EMPTY)87{88ASSERT (Nv [parent] > 0) ;89}90nels++ ;91}92}93}94AMD_DEBUG1 (("\n\nGo through the children of each node, and put\n"95"the biggest child last in each list:\n")) ;96#endif9798/* --------------------------------------------------------------------- */99/* place the largest child last in the list of children for each node */100/* --------------------------------------------------------------------- */101102for (i = 0 ; i < nn ; i++)103{104if (Nv [i] > 0 && Child [i] != EMPTY)105{106107#ifndef NDEBUG108Int nchild ;109AMD_DEBUG1 (("Before partial sort, element "ID"\n", i)) ;110nchild = 0 ;111for (f = Child [i] ; f != EMPTY ; f = Sibling [f])112{113ASSERT (f >= 0 && f < nn) ;114AMD_DEBUG1 ((" f: "ID" size: "ID"\n", f, Fsize [f])) ;115nchild++ ;116ASSERT (nchild <= nn) ;117}118#endif119120/* find the biggest element in the child list */121fprev = EMPTY ;122maxfrsize = EMPTY ;123bigfprev = EMPTY ;124bigf = EMPTY ;125for (f = Child [i] ; f != EMPTY ; f = Sibling [f])126{127ASSERT (f >= 0 && f < nn) ;128frsize = Fsize [f] ;129if (frsize >= maxfrsize)130{131/* this is the biggest seen so far */132maxfrsize = frsize ;133bigfprev = fprev ;134bigf = f ;135}136fprev = f ;137}138ASSERT (bigf != EMPTY) ;139140fnext = Sibling [bigf] ;141142AMD_DEBUG1 (("bigf "ID" maxfrsize "ID" bigfprev "ID" fnext "ID143" fprev " ID"\n", bigf, maxfrsize, bigfprev, fnext, fprev)) ;144145if (fnext != EMPTY)146{147/* if fnext is EMPTY then bigf is already at the end of list */148149if (bigfprev == EMPTY)150{151/* delete bigf from the element of the list */152Child [i] = fnext ;153}154else155{156/* delete bigf from the middle of the list */157Sibling [bigfprev] = fnext ;158}159160/* put bigf at the end of the list */161Sibling [bigf] = EMPTY ;162ASSERT (Child [i] != EMPTY) ;163ASSERT (fprev != bigf) ;164ASSERT (fprev != EMPTY) ;165Sibling [fprev] = bigf ;166}167168#ifndef NDEBUG169AMD_DEBUG1 (("After partial sort, element "ID"\n", i)) ;170for (f = Child [i] ; f != EMPTY ; f = Sibling [f])171{172ASSERT (f >= 0 && f < nn) ;173AMD_DEBUG1 ((" "ID" "ID"\n", f, Fsize [f])) ;174ASSERT (Nv [f] > 0) ;175nchild-- ;176}177ASSERT (nchild == 0) ;178#endif179180}181}182183/* --------------------------------------------------------------------- */184/* postorder the assembly tree */185/* --------------------------------------------------------------------- */186187for (i = 0 ; i < nn ; i++)188{189Order [i] = EMPTY ;190}191192k = 0 ;193194for (i = 0 ; i < nn ; i++)195{196if (Parent [i] == EMPTY && Nv [i] > 0)197{198AMD_DEBUG1 (("Root of assembly tree "ID"\n", i)) ;199k = AMD_post_tree (i, k, Child, Sibling, Order, Stack200#ifndef NDEBUG201, nn202#endif203) ;204}205}206}207208209