home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 300-399 / ff397.lzh / DKBTrace / DKBSource.LZH / prioq.c < prev    next >
C/C++ Source or Header  |  1990-08-26  |  5KB  |  200 lines

  1. /*****************************************************************************
  2. *
  3. *                                    prioq.c
  4. *
  5. *   from DKBTrace (c) 1990  David Buck
  6. *
  7. *  This module implements a priority queue using a heap.
  8. *
  9. * This software is freely distributable. The source and/or object code may be
  10. * copied or uploaded to communications services so long as this notice remains
  11. * at the top of each file.  If any changes are made to the program, you must
  12. * clearly indicate in the documentation and in the programs startup message
  13. * who it was who made the changes. The documentation should also describe what
  14. * those changes were. This software may not be included in whole or in
  15. * part into any commercial package without the express written consent of the
  16. * author.  It may, however, be included in other public domain or freely
  17. * distributed software so long as the proper credit for the software is given.
  18. *
  19. * This software is provided as is without any guarantees or warranty. Although
  20. * the author has attempted to find and correct any bugs in the software, he
  21. * is not responsible for any damage caused by the use of the software.  The
  22. * author is under no obligation to provide service, corrections, or upgrades
  23. * to this package.
  24. *
  25. * Despite all the legal stuff above, if you do find bugs, I would like to hear
  26. * about them.  Also, if you have any comments or questions, you may contact me
  27. * at the following address:
  28. *
  29. *     David Buck
  30. *     22C Sonnet Cres.
  31. *     Nepean Ontario
  32. *     Canada, K2H 8W7
  33. *
  34. *  I can also be reached on the following bulleton boards:
  35. *
  36. *     ATX              (613) 526-4141
  37. *     OMX              (613) 731-3419
  38. *     Mystic           (613) 731-0088 or (613) 731-6698
  39. *
  40. *  Fidonet:   1:163/109.9
  41. *  Internet:  David_Buck@Carleton.CA
  42. *
  43. *  IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es:
  44. *
  45. *     Lattice BBS                      (708) 916-1200
  46. *     The Information Exchange BBS     (708) 945-5575
  47. *     Stillwaters BBS                  (708) 403-2826
  48. *
  49. *****************************************************************************/
  50.  
  51. #include "frame.h"
  52. #include "dkbproto.h"
  53.  
  54. #define NUMBER_OF_PRIOQS 20
  55. #define NUMBER_OF_INTERSECTIONS 20
  56.  
  57. PRIOQ *prioqs;
  58.  
  59. void pq_init ()
  60.    {
  61.    register int i;
  62.    PRIOQ *new_pq;
  63.  
  64.    prioqs = NULL;
  65.  
  66.    for (i = 0 ; i < NUMBER_OF_PRIOQS; i++)
  67.       {
  68.       if ((new_pq = (PRIOQ *) malloc (sizeof (PRIOQ))) == NULL) {
  69.          printf ("\nCannot allocate queues");
  70.          exit(1);
  71.          }
  72.       
  73.       new_pq -> next_pq = prioqs;
  74.       prioqs = new_pq;
  75.  
  76.       if ((new_pq -> queue = (INTERSECTION *)
  77.             malloc (128 * sizeof (INTERSECTION))) == NULL) {
  78.          printf ("\nCannot allocate queue entries");
  79.          exit(1);
  80.          }
  81.       }
  82.    }
  83.  
  84. PRIOQ *pq_alloc()
  85.    {
  86.    PRIOQ *allocated_queue;
  87.  
  88.    if (prioqs == NULL) {
  89.       printf ("\nOut of prioqs");
  90.       exit(1);
  91.       }
  92.  
  93.    allocated_queue = prioqs;
  94.    prioqs = allocated_queue -> next_pq;
  95.    return (allocated_queue);
  96.    }
  97.  
  98. void pq_free (pq)
  99.    PRIOQ *pq;
  100.    {
  101.    pq -> next_pq = prioqs;
  102.    prioqs = pq;
  103.    }
  104.  
  105. PRIOQ *pq_new (index_size)
  106.    int index_size;
  107.    {
  108.    PRIOQ *pq;
  109.  
  110.    if (index_size > 256)
  111.       return (NULL);
  112.  
  113.    if ((pq = pq_alloc()) == NULL)
  114.       return (NULL);
  115.  
  116.    pq -> queue_size = index_size;
  117.    pq -> current_entry = 0;
  118.    return (pq);
  119.    }
  120.  
  121. void pq_balance(q, entry_pos1)
  122.    PRIOQ *q;
  123.    unsigned int entry_pos1;
  124.    {
  125.    register INTERSECTION *entry1, *entry2;
  126.    INTERSECTION temp_entry;
  127.    register unsigned int entry_pos2;
  128.  
  129.    entry1 = &q->queue[entry_pos1];
  130.  
  131.    if ((entry_pos1 * 2 < q->queue_size)
  132.        && (entry_pos1 * 2 <= q -> current_entry))
  133.       {
  134.       if ((entry_pos1*2+1 > q->current_entry) ||
  135.           (q->queue[entry_pos1*2].Depth < q->queue[entry_pos1*2+1].Depth))
  136.          entry_pos2 = entry_pos1*2;
  137.       else
  138.          entry_pos2 = entry_pos1*2+1;
  139.  
  140.       entry2 = &q->queue[entry_pos2];
  141.  
  142.       if (entry1->Depth > entry2->Depth) {
  143.          temp_entry = *entry1;
  144.          *entry1 = *entry2;
  145.          *entry2 = temp_entry;
  146.          pq_balance (q, entry_pos2);
  147.          }
  148.       }
  149.  
  150.    if (entry_pos1 / 2 >= 1 )
  151.       {
  152.       entry_pos2 = entry_pos1 / 2;
  153.       entry2 = &q->queue[entry_pos2];
  154.       if (entry1->Depth < entry2->Depth) {
  155.          temp_entry = *entry1;
  156.          *entry1 = *entry2;
  157.          *entry2 = temp_entry;
  158.          pq_balance (q, entry_pos2);
  159.          }
  160.       }
  161.    }
  162.  
  163. void pq_add (q, entry)
  164.    PRIOQ *q;
  165.    INTERSECTION *entry;
  166.    {
  167.    q -> current_entry++;
  168.    if (q -> current_entry >= q -> queue_size)
  169.       q -> current_entry--;
  170.  
  171.    q -> queue [q -> current_entry] = *entry;
  172.    pq_balance (q, q -> current_entry);
  173.    }
  174.  
  175. INTERSECTION *pq_get_highest(q)
  176.    PRIOQ *q;
  177.    {
  178.    if (q -> current_entry >= 1)
  179.       return (&(q -> queue[1]));
  180.    else
  181.       return (NULL);
  182.    }
  183.  
  184. int pq_is_empty(q)
  185.    PRIOQ *q;
  186.    {
  187.    if (q -> current_entry < 1)
  188.       return (TRUE);
  189.    else
  190.       return (FALSE);
  191.    }
  192.  
  193. void pq_delete_highest (q)
  194.    PRIOQ *q;
  195.    {
  196.    q -> queue[1] = q -> queue[q -> current_entry--];
  197.    pq_balance (q, 1);
  198.    }
  199.  
  200.