amd_post_tree.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /* ========================================================================= */
  2. /* === AMD_post_tree ======================================================= */
  3. /* ========================================================================= */
  4. /* ------------------------------------------------------------------------- */
  5. /* AMD, Copyright (c) Timothy A. Davis, */
  6. /* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */
  7. /* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */
  8. /* web: http://www.cise.ufl.edu/research/sparse/amd */
  9. /* ------------------------------------------------------------------------- */
  10. /* Post-ordering of a supernodal elimination tree. */
  11. #include "amd_internal.h"
  12. GLOBAL Int AMD_post_tree
  13. (
  14. Int root, /* root of the tree */
  15. Int k, /* start numbering at k */
  16. Int Child [ ], /* input argument of size nn, undefined on
  17. * output. Child [i] is the head of a link
  18. * list of all nodes that are children of node
  19. * i in the tree. */
  20. const Int Sibling [ ], /* input argument of size nn, not modified.
  21. * If f is a node in the link list of the
  22. * children of node i, then Sibling [f] is the
  23. * next child of node i.
  24. */
  25. Int Order [ ], /* output order, of size nn. Order [i] = k
  26. * if node i is the kth node of the reordered
  27. * tree. */
  28. Int Stack [ ] /* workspace of size nn */
  29. #ifndef NDEBUG
  30. , Int nn /* nodes are in the range 0..nn-1. */
  31. #endif
  32. )
  33. {
  34. Int f, head, h, i ;
  35. #if 0
  36. /* --------------------------------------------------------------------- */
  37. /* recursive version (Stack [ ] is not used): */
  38. /* --------------------------------------------------------------------- */
  39. /* this is simple, but can caouse stack overflow if nn is large */
  40. i = root ;
  41. for (f = Child [i] ; f != EMPTY ; f = Sibling [f])
  42. {
  43. k = AMD_post_tree (f, k, Child, Sibling, Order, Stack, nn) ;
  44. }
  45. Order [i] = k++ ;
  46. return (k) ;
  47. #endif
  48. /* --------------------------------------------------------------------- */
  49. /* non-recursive version, using an explicit stack */
  50. /* --------------------------------------------------------------------- */
  51. /* push root on the stack */
  52. head = 0 ;
  53. Stack [0] = root ;
  54. while (head >= 0)
  55. {
  56. /* get head of stack */
  57. ASSERT (head < nn) ;
  58. i = Stack [head] ;
  59. AMD_DEBUG1 (("head of stack "ID" \n", i)) ;
  60. ASSERT (i >= 0 && i < nn) ;
  61. if (Child [i] != EMPTY)
  62. {
  63. /* the children of i are not yet ordered */
  64. /* push each child onto the stack in reverse order */
  65. /* so that small ones at the head of the list get popped first */
  66. /* and the biggest one at the end of the list gets popped last */
  67. for (f = Child [i] ; f != EMPTY ; f = Sibling [f])
  68. {
  69. head++ ;
  70. ASSERT (head < nn) ;
  71. ASSERT (f >= 0 && f < nn) ;
  72. }
  73. h = head ;
  74. ASSERT (head < nn) ;
  75. for (f = Child [i] ; f != EMPTY ; f = Sibling [f])
  76. {
  77. ASSERT (h > 0) ;
  78. Stack [h--] = f ;
  79. AMD_DEBUG1 (("push "ID" on stack\n", f)) ;
  80. ASSERT (f >= 0 && f < nn) ;
  81. }
  82. ASSERT (Stack [h] == i) ;
  83. /* delete child list so that i gets ordered next time we see it */
  84. Child [i] = EMPTY ;
  85. }
  86. else
  87. {
  88. /* the children of i (if there were any) are already ordered */
  89. /* remove i from the stack and order it. Front i is kth front */
  90. head-- ;
  91. AMD_DEBUG1 (("pop "ID" order "ID"\n", i, k)) ;
  92. Order [i] = k++ ;
  93. ASSERT (k <= nn) ;
  94. }
  95. #ifndef NDEBUG
  96. AMD_DEBUG1 (("\nStack:")) ;
  97. for (h = head ; h >= 0 ; h--)
  98. {
  99. Int j = Stack [h] ;
  100. AMD_DEBUG1 ((" "ID, j)) ;
  101. ASSERT (j >= 0 && j < nn) ;
  102. }
  103. AMD_DEBUG1 (("\n\n")) ;
  104. ASSERT (head < nn) ;
  105. #endif
  106. }
  107. return (k) ;
  108. }