source: trunk/indexers/mg/lib/mgheap.c@ 3745

Last change on this file since 3745 was 3745, checked in by mdewsnip, 21 years ago

Addition of MG package for search and retrieval

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 4.5 KB
Line 
1/**************************************************************************
2 *
3 * mgheap.c -- Heap routines
4 * Copyright (C) 1994 Neil Sharman
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 * $Id: mgheap.c 3745 2003-02-20 21:20:24Z mdewsnip $
21 *
22 **************************************************************************/
23
24/*
25 $Log$
26 Revision 1.1 2003/02/20 21:14:16 mdewsnip
27 Addition of MG package for search and retrieval
28
29 Revision 1.1 1999/08/10 21:16:55 sjboddie
30 renamed mg-1.3d directory mg
31
32 Revision 1.1 1999/01/15 03:05:50 rjmcnab
33
34 Renamed lib/heap to be lib/mgheap (it was causing some problems with
35 some versions of the STL libraries which contained a heap.h)
36
37 Revision 1.1 1998/11/17 09:32:01 rjmcnab
38 *** empty log message ***
39
40 * Revision 1.1 1994/08/22 00:24:43 tes
41 * Initial placement under CVS.
42 *
43 */
44
45static char *RCSID = "$Id: mgheap.c 3745 2003-02-20 21:20:24Z mdewsnip $";
46
47#include "mgheap.h"
48
49#define SWAP(s, a, b) \
50do { \
51 register int __i; \
52 register char *__a = (a), *__b = (b); \
53 for (__i = (s); __i; __i--) \
54 { \
55 register char __t = *__a; \
56 *__a++ = *__b; *__b++ = __t; \
57 } \
58} while(0)
59
60
61
62#define COPY(s, dst, src) \
63do { \
64 register int __i; \
65 register char *__dst = (dst), *__src = (src); \
66 for (__i = (s); __i; __i--) \
67 *__dst++ = *__src++; \
68} while(0)
69
70
71
72static void
73heap_heapify (void *heap, int size, int num, int curr, heap_comp hc)
74{
75 register int child = curr * 2;
76 while (child <= num)
77 {
78 if (child < num && hc ((char *) heap + child * size,
79 (char *) heap + child * size - size) < 0)
80 child++;
81 if (hc ((char *) heap + (curr - 1) * size, (char *) heap + (child - 1) * size) > 0)
82 {
83 SWAP (size, (char *) heap + (curr - 1) * size,
84 (char *) heap + (child - 1) * size);
85 curr = child;
86 child = child * 2;
87 }
88 else
89 break;
90 }
91}
92
93static void
94heap_pullup (void *heap, int size, int num, heap_comp hc)
95{
96 register int curr = num;
97 register int parent = curr >> 1;
98 while (parent &&
99 hc ((char *) heap + (curr - 1) * size, (char *) heap + (parent - 1) * size) < 0)
100 {
101 SWAP (size, (char *) heap + (curr - 1) * size,
102 (char *) heap + (parent - 1) * size);
103 curr = parent;
104 parent = curr >> 1;
105 }
106}
107
108/************************************************************************
109 *
110 * NOTE: If you choose to change the comparison function the first thing
111 * you do after changing the function is call heap_build.
112 *
113 */
114void
115heap_build (void *heap, int size, int num, heap_comp hc)
116{
117 register int i;
118 for (i = num / 2; i > 0; i--)
119 heap_heapify (heap, size, num, i, hc);
120}
121
122
123
124/****************************************************
125 *
126 * NOTE : The heap must be built before heap_sort is called.
127 * This has the effect of reversing the order of the array.
128 * e.g. if your comparison function is designed to pull the
129 * biggest thing off the heap first then the result of
130 * sorting with this function will be to put the bigest
131 * thing at the end of the array.
132 *
133 */
134void
135heap_sort (void *heap, int size, int num, heap_comp hc)
136{
137 register int i;
138 for (i = num; i > 1; i--)
139 {
140 SWAP (size, heap, (char *) heap + (i - 1) * size);
141 heap_heapify (heap, size, i - 1, 1, hc);
142 }
143}
144
145
146void
147heap_deletehead (void *heap, int size, int *num, heap_comp hc)
148{
149 (*num)--;
150 SWAP (size, heap, (char *) heap + *num * size);
151 heap_heapify (heap, size, *num, 1, hc);
152}
153
154
155void
156heap_changedhead (void *heap, int size, int num, heap_comp hc)
157{
158 heap_heapify (heap, size, num, 1, hc);
159}
160
161
162/***********************************************************************
163 *
164 * This assumes that the item has been added to the end of the
165 * array that is the heap. But that num has not been changed.
166 *
167 */
168void
169heap_additem (void *heap, int size, int *num, heap_comp hc)
170{
171 (*num)++;
172 heap_pullup (heap, size, *num, hc);
173}
Note: See TracBrowser for help on using the repository browser.