1 /* Barebones heap implementation supporting only insert and pop.
3 Copyright (C) 2010-2023 Free Software Foundation, Inc.
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU 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, see <https://www.gnu.org/licenses/>. */
18 /* Full implementation: GDSL (http://gna.org/projects/gdsl/) by Nicolas
19 Darnis <ndarnis@free.fr>. */
27 static int heap_default_compare (void const *, void const *);
28 static size_t heapify_down (void **, size_t, size_t,
29 int (*) (void const *, void const *));
30 static void heapify_up (void **, size_t,
31 int (*) (void const *, void const *));
35 void **array
; /* array[0] is not used */
36 size_t capacity
; /* Array size */
37 size_t count
; /* Used as index to last element. Also is num of items. */
38 int (*compare
) (void const *, void const *);
41 /* Allocate memory for the heap. */
44 heap_alloc (int (*compare
) (void const *, void const *), size_t n_reserve
)
46 struct heap
*heap
= xmalloc (sizeof *heap
);
51 heap
->array
= xnmalloc (n_reserve
, sizeof *(heap
->array
));
53 heap
->array
[0] = nullptr;
54 heap
->capacity
= n_reserve
;
56 heap
->compare
= compare
? compare
: heap_default_compare
;
63 heap_default_compare (void const *a
, void const *b
)
70 heap_free (struct heap
*heap
)
76 /* Insert element into heap. */
79 heap_insert (struct heap
*heap
, void *item
)
81 if (heap
->capacity
- 1 <= heap
->count
)
82 heap
->array
= x2nrealloc (heap
->array
, &heap
->capacity
,
83 sizeof *(heap
->array
));
85 heap
->array
[++heap
->count
] = item
;
86 heapify_up (heap
->array
, heap
->count
, heap
->compare
);
91 /* Pop top element off heap. */
94 heap_remove_top (struct heap
*heap
)
101 top
= heap
->array
[1];
102 heap
->array
[1] = heap
->array
[heap
->count
--];
103 heapify_down (heap
->array
, heap
->count
, 1, heap
->compare
);
108 /* Move element down into appropriate position in heap. */
111 heapify_down (void **array
, size_t count
, size_t initial
,
112 int (*compare
) (void const *, void const *))
114 void *element
= array
[initial
];
116 size_t parent
= initial
;
117 while (parent
<= count
/ 2)
119 size_t child
= 2 * parent
;
121 if (child
< count
&& compare (array
[child
], array
[child
+ 1]) < 0)
124 if (compare (array
[child
], element
) <= 0)
127 array
[parent
] = array
[child
];
131 array
[parent
] = element
;
135 /* Move element up into appropriate position in heap. */
138 heapify_up (void **array
, size_t count
,
139 int (*compare
) (void const *, void const *))
142 void *new_element
= array
[k
];
144 while (k
!= 1 && compare (array
[k
/ 2], new_element
) <= 0)
146 array
[k
] = array
[k
/ 2];
150 array
[k
] = new_element
;