1 /* PSPP - computes sample statistics.
2 Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
3 Written by Ben Pfaff <blp@gnu.org>.
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
27 #define GLOBAL_DEBUGGING 1
31 /* Creates and returns a heap with an initial capacity of M_ELEM
32 elements. Returns nonzero only if successful. */
34 heap_create (size_t m_elem)
36 struct heap *h = malloc (sizeof *h);
41 h->elem = malloc (h->m_elem * sizeof *h->elem);
51 /* Destroys the heap at *H. */
53 heap_destroy (struct heap *h)
60 /* Inserts into heap *H an element having index INDEX and key KEY.
61 Returns nonzero only if successful. */
63 heap_insert (struct heap *h, int index, int key)
68 if (h->n_elem >= h->m_elem)
70 h->elem = realloc (h->elem, 2 * h->m_elem * sizeof *h->elem);
76 /* Knuth's Algorithm 5.2.3-16. Step 1. */
85 if (i == 0 || h->elem[i - 1].key <= key)
87 h->elem[j - 1].index = index;
88 h->elem[j - 1].key = key;
94 h->elem[j - 1] = h->elem[i - 1];
99 /* Deletes the first element in the heap (the one with the greatest
100 index) and returns its index, or -1 if the heap is empty. If KEY
101 is non-NULL then *KEY is set to the deleted element's key, if it
104 heap_delete (struct heap *h, int *key)
106 /* Knuth's Algorithm 5.2.3H-19. */
107 int first, K, R, l, r, i, j;
111 first = h->elem[0].index;
113 *key = h->elem[0].key;
114 K = h->elem[h->n_elem - 1].key;
115 R = h->elem[h->n_elem - 1].index;
131 if (h->elem[j - 1].key > h->elem[j].key)
135 if (K <= h->elem[j - 1].key)
139 h->elem[i - 1] = h->elem[j - 1];
143 h->elem[i - 1].key = K;
144 h->elem[i - 1].index = R;
150 /* Returns the number of elements in heap H. */
152 heap_size (struct heap *h)
158 /* Checks that a heap is really a heap. */
160 heap_verify (const struct heap *h)
164 for (j = 1; j <= h->n_elem; j++)
166 if (j / 2 >= 1 && h->elem[j / 2 - 1].key > h->elem[j - 1].key)
167 printf (_("bad ordering of keys %d and %d\n"), j / 2 - 1, j - 1);
171 /* Dumps out the heap on stdout. */
173 heap_dump (const struct heap *h)
177 printf (_("Heap contents:\n"));
178 for (j = 1; j <= h->n_elem; j++)
182 partner = h->elem[j / 2 - 1].key;
185 printf ("%6d-%5d", h->elem[j - 1].key, partner);
188 #endif /* GLOBAL_DEBUGGING */
193 /* To perform a fairly thorough test of the heap routines, define
194 STANDALONE to nonzero then compile this file by itself. */
196 /* Compares the second elements of the integer arrays at _A and _B and
197 returns a strcmp()-type result. */
199 compare_int2 (const void *pa, const void *pb)
209 /* Arrange the N elements of ARRAY in random order. */
211 shuffle (int (*array)[2], int n)
215 for (i = 0; i < n; i++)
217 int j = i + rand () % (n - i);
218 int t = array[j][0], s = array[j][1];
219 array[j][0] = array[i][0], array[j][1] = array[i][1];
220 array[i][0] = t, array[i][1] = s;
230 int array[N_ELEM][2];
234 h = heap_create (16);
235 for (i = 0; i < N_ELEM; i++)
238 array[i][1] = N_ELEM - i - 1;
240 shuffle (array, N_ELEM);
242 printf ("Insertion order:\n");
243 for (i = 0; i < N_ELEM; i++)
245 printf ("(%d,%d) ", array[i][0], array[i][1]);
246 heap_insert (h, array[i][0], array[i][1]);
253 printf ("\nDeletion order:\n");
254 for (i = 0; i < N_ELEM; i++)
257 index = heap_delete (h, &key);
258 assert (index != -1);
259 printf ("(%d,%d) ", index, key);
261 assert (index == N_ELEM - i - 1 && key == i);