123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- /*
- Module: Arbitrary-In Sorted-Out (AISO)
- Author: [email protected] (Dick Grune @ Vrije Universiteit, Amsterdam)
- Description:
- This is the body of a module that builds an arbitrary-in
- sorted-out data structure, to be used as a heap, a priority queue, etc.
- See aiso.spc for further info.
- */
- #include <malloc.h>
- static struct aiso_node *root; /* root of tree */
- #ifdef AISO_ITERATOR
- static struct aiso_node *list; /* start of linked list */
- #endif /* AISO_ITERATOR */
- /* the policy */
- static int aiso_size = 0;
- static int access_mark = 1;
- #define add_entry() (aiso_size++)
- #define remove_entry() (aiso_size--)
- #define reset_access() (access_mark = 1)
- #define count_access() (access_mark <<= 1)
- #define must_rotate() (access_mark > aiso_size)
- int
- InsertAiso(AISO_TYPE v) {
- register struct aiso_node *new_node;
- register struct aiso_node **hook = &root;
- #ifdef AISO_ITERATOR
- register struct aiso_node **prev = &list;
- #endif /* AISO_ITERATOR */
- new_node = (struct aiso_node *)malloc(sizeof (struct aiso_node));
- if (!new_node) {
- /* avoid modifying the tree */
- return 0;
- }
- while (*hook) {
- register struct aiso_node *an = *hook;
- count_access();
- if (AISO_BEFORE(v, an->an_value)) {
- /* head left */
- if (!an->an_left || !must_rotate()) {
- /* standard action */
- hook = &an->an_left;
- }
- else {
- /* change (l A r) B (C) into (l) A (r B C) */
- register struct aiso_node *anl = an->an_left;
- an->an_left = anl->an_right;
- anl->an_right = an;
- *hook = anl;
- reset_access();
- }
- }
- else {
- /* head right */
- if (!an->an_right || !must_rotate()) {
- /* standard action */
- hook = &an->an_right;
- }
- else {
- /* change (A) B (l C r) into (A B l) C (r) */
- register struct aiso_node *anr = an->an_right;
- an->an_right = anr->an_left;
- anr->an_left = an;
- *hook = anr;
- reset_access();
- }
- #ifdef AISO_ITERATOR
- prev = &an->an_next;
- #endif /* AISO_ITERATOR */
- }
- }
- new_node->an_left = 0;
- new_node->an_right = 0;
- #ifdef AISO_ITERATOR
- new_node->an_next = *prev;
- *prev = new_node;
- #endif /* AISO_ITERATOR */
- new_node->an_value = v;
- *hook = new_node;
- add_entry();
- return 1;
- }
- #ifdef AISO_EXTRACTOR
- int
- ExtractAiso(AISO_TYPE *vp) {
- register struct aiso_node **hook = &root;
- register struct aiso_node *an;
- if (!root) return 0;
- while ((an = *hook), an->an_left) {
- /* head left */
- count_access();
- if (!must_rotate()) {
- /* standard action */
- hook = &an->an_left;
- }
- else {
- /* change (l A r) B (C) into (l) A (r B C) */
- register struct aiso_node *anl = an->an_left;
- an->an_left = anl->an_right;
- anl->an_right = an;
- *hook = anl;
- reset_access();
- }
- }
- /* found the first */
- *vp = an->an_value;
- *hook = an->an_right;
- #ifdef AISO_ITERATOR
- list = an->an_next;
- #endif /* AISO_ITERATOR */
- free((char *)an);
- remove_entry();
- return 1;
- }
- #endif /* AISO_EXTRACTOR */
- #ifdef AISO_ITERATOR
- void
- OpenIter(AisoIter *ip) {
- *ip = list;
- }
- int
- GetAisoItem(AisoIter *ip, AISO_TYPE *vp) {
- register struct aiso_node *an = *ip;
- if (!an) return 0;
- *vp = an->an_value;
- *ip = an->an_next;
- return 1;
- }
- void
- CloseIter(AisoIter *ip) {
- *ip = 0;
- }
- #endif /* AISO_ITERATOR */
- #ifdef AISO_DEBUG
- #include <stdio.h>
- static void
- print_inf(int level, char ch, struct aiso_node *an) {
- register int i;
- if (!an) return;
- print_inf(level+1, '/', an->an_right);
- for (i = 0; i < level; i++) {
- printf(" ");
- }
- printf("%c", ch);
- printf(AISO_FORMAT, an->an_value);
- printf("\n");
- print_inf(level+1, '\\', an->an_left);
- }
- void
- PrintAisoTree(void)
- {
- print_inf(0, '-', root);
- printf("================\n");
- }
- #endif /* AISO_DEBUG */
|