aiso.bdy 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /*
  2. Module: Arbitrary-In Sorted-Out (AISO)
  3. Author: [email protected] (Dick Grune @ Vrije Universiteit, Amsterdam)
  4. Description:
  5. This is the body of a module that builds an arbitrary-in
  6. sorted-out data structure, to be used as a heap, a priority queue, etc.
  7. See aiso.spc for further info.
  8. */
  9. #include <malloc.h>
  10. static struct aiso_node *root; /* root of tree */
  11. #ifdef AISO_ITERATOR
  12. static struct aiso_node *list; /* start of linked list */
  13. #endif /* AISO_ITERATOR */
  14. /* the policy */
  15. static int aiso_size = 0;
  16. static int access_mark = 1;
  17. #define add_entry() (aiso_size++)
  18. #define remove_entry() (aiso_size--)
  19. #define reset_access() (access_mark = 1)
  20. #define count_access() (access_mark <<= 1)
  21. #define must_rotate() (access_mark > aiso_size)
  22. int
  23. InsertAiso(AISO_TYPE v) {
  24. register struct aiso_node *new_node;
  25. register struct aiso_node **hook = &root;
  26. #ifdef AISO_ITERATOR
  27. register struct aiso_node **prev = &list;
  28. #endif /* AISO_ITERATOR */
  29. new_node = (struct aiso_node *)malloc(sizeof (struct aiso_node));
  30. if (!new_node) {
  31. /* avoid modifying the tree */
  32. return 0;
  33. }
  34. while (*hook) {
  35. register struct aiso_node *an = *hook;
  36. count_access();
  37. if (AISO_BEFORE(v, an->an_value)) {
  38. /* head left */
  39. if (!an->an_left || !must_rotate()) {
  40. /* standard action */
  41. hook = &an->an_left;
  42. }
  43. else {
  44. /* change (l A r) B (C) into (l) A (r B C) */
  45. register struct aiso_node *anl = an->an_left;
  46. an->an_left = anl->an_right;
  47. anl->an_right = an;
  48. *hook = anl;
  49. reset_access();
  50. }
  51. }
  52. else {
  53. /* head right */
  54. if (!an->an_right || !must_rotate()) {
  55. /* standard action */
  56. hook = &an->an_right;
  57. }
  58. else {
  59. /* change (A) B (l C r) into (A B l) C (r) */
  60. register struct aiso_node *anr = an->an_right;
  61. an->an_right = anr->an_left;
  62. anr->an_left = an;
  63. *hook = anr;
  64. reset_access();
  65. }
  66. #ifdef AISO_ITERATOR
  67. prev = &an->an_next;
  68. #endif /* AISO_ITERATOR */
  69. }
  70. }
  71. new_node->an_left = 0;
  72. new_node->an_right = 0;
  73. #ifdef AISO_ITERATOR
  74. new_node->an_next = *prev;
  75. *prev = new_node;
  76. #endif /* AISO_ITERATOR */
  77. new_node->an_value = v;
  78. *hook = new_node;
  79. add_entry();
  80. return 1;
  81. }
  82. #ifdef AISO_EXTRACTOR
  83. int
  84. ExtractAiso(AISO_TYPE *vp) {
  85. register struct aiso_node **hook = &root;
  86. register struct aiso_node *an;
  87. if (!root) return 0;
  88. while ((an = *hook), an->an_left) {
  89. /* head left */
  90. count_access();
  91. if (!must_rotate()) {
  92. /* standard action */
  93. hook = &an->an_left;
  94. }
  95. else {
  96. /* change (l A r) B (C) into (l) A (r B C) */
  97. register struct aiso_node *anl = an->an_left;
  98. an->an_left = anl->an_right;
  99. anl->an_right = an;
  100. *hook = anl;
  101. reset_access();
  102. }
  103. }
  104. /* found the first */
  105. *vp = an->an_value;
  106. *hook = an->an_right;
  107. #ifdef AISO_ITERATOR
  108. list = an->an_next;
  109. #endif /* AISO_ITERATOR */
  110. free((char *)an);
  111. remove_entry();
  112. return 1;
  113. }
  114. #endif /* AISO_EXTRACTOR */
  115. #ifdef AISO_ITERATOR
  116. void
  117. OpenIter(AisoIter *ip) {
  118. *ip = list;
  119. }
  120. int
  121. GetAisoItem(AisoIter *ip, AISO_TYPE *vp) {
  122. register struct aiso_node *an = *ip;
  123. if (!an) return 0;
  124. *vp = an->an_value;
  125. *ip = an->an_next;
  126. return 1;
  127. }
  128. void
  129. CloseIter(AisoIter *ip) {
  130. *ip = 0;
  131. }
  132. #endif /* AISO_ITERATOR */
  133. #ifdef AISO_DEBUG
  134. #include <stdio.h>
  135. static void
  136. print_inf(int level, char ch, struct aiso_node *an) {
  137. register int i;
  138. if (!an) return;
  139. print_inf(level+1, '/', an->an_right);
  140. for (i = 0; i < level; i++) {
  141. printf(" ");
  142. }
  143. printf("%c", ch);
  144. printf(AISO_FORMAT, an->an_value);
  145. printf("\n");
  146. print_inf(level+1, '\\', an->an_left);
  147. }
  148. void
  149. PrintAisoTree(void)
  150. {
  151. print_inf(0, '-', root);
  152. printf("================\n");
  153. }
  154. #endif /* AISO_DEBUG */