/* ========================================================================= */1/* === AMD_post_tree ======================================================= */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/* Post-ordering of a supernodal elimination tree. */1213#include "amd_internal.h"1415GLOBAL Int AMD_post_tree16(17Int root, /* root of the tree */18Int k, /* start numbering at k */19Int Child [ ], /* input argument of size nn, undefined on20* output. Child [i] is the head of a link21* list of all nodes that are children of node22* i in the tree. */23const Int Sibling [ ], /* input argument of size nn, not modified.24* If f is a node in the link list of the25* children of node i, then Sibling [f] is the26* next child of node i.27*/28Int Order [ ], /* output order, of size nn. Order [i] = k29* if node i is the kth node of the reordered30* tree. */31Int Stack [ ] /* workspace of size nn */32#ifndef NDEBUG33, Int nn /* nodes are in the range 0..nn-1. */34#endif35)36{37Int f, head, h, i ;3839#if 040/* --------------------------------------------------------------------- */41/* recursive version (Stack [ ] is not used): */42/* --------------------------------------------------------------------- */4344/* this is simple, but can caouse stack overflow if nn is large */45i = root ;46for (f = Child [i] ; f != EMPTY ; f = Sibling [f])47{48k = AMD_post_tree (f, k, Child, Sibling, Order, Stack, nn) ;49}50Order [i] = k++ ;51return (k) ;52#endif5354/* --------------------------------------------------------------------- */55/* non-recursive version, using an explicit stack */56/* --------------------------------------------------------------------- */5758/* push root on the stack */59head = 0 ;60Stack [0] = root ;6162while (head >= 0)63{64/* get head of stack */65ASSERT (head < nn) ;66i = Stack [head] ;67AMD_DEBUG1 (("head of stack "ID" \n", i)) ;68ASSERT (i >= 0 && i < nn) ;6970if (Child [i] != EMPTY)71{72/* the children of i are not yet ordered */73/* push each child onto the stack in reverse order */74/* so that small ones at the head of the list get popped first */75/* and the biggest one at the end of the list gets popped last */76for (f = Child [i] ; f != EMPTY ; f = Sibling [f])77{78head++ ;79ASSERT (head < nn) ;80ASSERT (f >= 0 && f < nn) ;81}82h = head ;83ASSERT (head < nn) ;84for (f = Child [i] ; f != EMPTY ; f = Sibling [f])85{86ASSERT (h > 0) ;87Stack [h--] = f ;88AMD_DEBUG1 (("push "ID" on stack\n", f)) ;89ASSERT (f >= 0 && f < nn) ;90}91ASSERT (Stack [h] == i) ;9293/* delete child list so that i gets ordered next time we see it */94Child [i] = EMPTY ;95}96else97{98/* the children of i (if there were any) are already ordered */99/* remove i from the stack and order it. Front i is kth front */100head-- ;101AMD_DEBUG1 (("pop "ID" order "ID"\n", i, k)) ;102Order [i] = k++ ;103ASSERT (k <= nn) ;104}105106#ifndef NDEBUG107AMD_DEBUG1 (("\nStack:")) ;108for (h = head ; h >= 0 ; h--)109{110Int j = Stack [h] ;111AMD_DEBUG1 ((" "ID, j)) ;112ASSERT (j >= 0 && j < nn) ;113}114AMD_DEBUG1 (("\n\n")) ;115ASSERT (head < nn) ;116#endif117118}119return (k) ;120}121122123