37#define LT(p,q) ((p).dist < (q).dist)
38#define EQ(p,q) ((p).dist == (q).dist)
60#define sub(h,i) (LIST_GET((h), (i)))
71#define left(i) (2*(i))
72#define right(i) (2*(i)+1)
73#define parent(i) ((i)/2)
74#define insideHeap(h,i) ((i)<h->heapSize)
75#define greaterPriority(h,i,j) \
76 (LT(h->data[i],h->data[j]) || ((EQ(h->data[i],h->data[j])) && (rand()%2)))
109 for (
size_t i = 0; n != 0 && i < n - 1; i++) {
110 edge.left = ordering[i];
111 edge.right = ordering[i + 1];
112 edge.dist = place[ordering[i + 1]] - place[ordering[i]];
115 for (
size_t j = (n - 1) / 2; n != 0 && j !=
SIZE_MAX; j--) {
136 size_t newSize = h->
maxSize * 2;
148static int cmp(
const void *a,
const void *b,
void *context) {
151 const double *place = context;
153 if (place[*x] < place[*y]) {
156 if (place[*x] > place[*y]) {
163 pairs_t* pairs_stack) {
171 size_t *ordering =
gv_calloc(n,
sizeof(
size_t));
172 size_t *inv_ordering =
gv_calloc(n,
sizeof(
size_t));
174 for (
size_t i = 0; i < n; i++) {
177 gv_sort(ordering, n,
sizeof(ordering[0]),
cmp, place);
178 for (
size_t i = 0; i < n; i++) {
179 inv_ordering[ordering[i]] = i;
186 for (
size_t i = 1; i < n; i++) {
187 left[ordering[i]] = ordering[i - 1];
189 for (
size_t i = 0; n != 0 && i < n - 1; i++) {
190 right[ordering[i]] = ordering[i + 1];
201 size_t left_index = inv_ordering[
pair.left];
202 size_t right_index = inv_ordering[
pair.right];
203 if (left_index > 0) {
204 size_t neighbor = ordering[left_index - 1];
208 new_pair.right =
pair.right;
215 if (right_index < n - 1) {
216 size_t neighbor = ordering[right_index + 1];
219 new_pair.left =
pair.left;
237 for (
size_t i = 0; i <
graph[u].nedges; i++) {
238 if (
graph[u].edges[i] == v) {
256 int *degrees =
gv_calloc(n,
sizeof(
int));
258 size_t new_nedges = 2 *
top + n;
260 int *edges =
gv_calloc(new_nedges,
sizeof(
int));
261 float *weights =
gv_calloc(new_nedges,
sizeof(
float));
263 for (
size_t i = 0; i < n; i++) {
266 for (
size_t i = 0; i <
top; i++) {
268 degrees[
pair.left]++;
269 degrees[
pair.right]++;
273 for (
size_t i = 0; i < new_nedges; i++) {
278 for (
size_t i = 0; i < n; i++) {
280 new_graph[i].
ewgts = weights;
281 new_graph[i].
edges = edges;
282 assert(i <= INT_MAX);
285 weights += degrees[i];
292 while (
pop(edges_stack, &
pair)) {
293 assert(
pair.left <= INT_MAX);
294 assert(
pair.right <= INT_MAX);
304 pairs_t pairs_stack = {0};
Memory allocation wrappers that exit on failure.
static void * gv_recalloc(void *ptr, size_t old_nmemb, size_t new_nmemb, size_t size)
static void * gv_calloc(size_t nmemb, size_t size)
#define greaterPriority(h, i, j)
static void find_closest_pairs(double *place, size_t n, int num_pairs, pairs_t *pairs_stack)
static void initHeap(PairHeap *h, double *place, size_t *ordering, size_t n)
static vtx_data * construct_graph(size_t n, pairs_t *edges_stack)
static void freeHeap(PairHeap *h)
void closest_pairs2graph(double *place, int n, int num_pairs, vtx_data **graph)
static bool extractMax(PairHeap *h, Pair *max)
static void add_edge(vtx_data *graph, int u, int v)
static void heapify(PairHeap *h, size_t i)
static void insert(PairHeap *h, Pair edge)
static int cmp(const void *a, const void *b, void *context)
static gstack_t * push(gstack_t *s, Agraph_t *subg)
Agraph_t * graph(char *name)
Arithmetic helper functions.
static Agedge_t * top(edge_stack_t *sp)
type-generic dynamically expanding list
#define LIST_DROP_BACK(list)
#define LIST_IS_EMPTY(list)
#define LIST_PUSH_BACK(list, item)
#define neighbor(t, i, edim, elist)
qsort with carried along context
static void gv_sort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *, void *), void *arg)
qsort with an extra state parameter, ala qsort_r
size_t right
the right node in the pair
size_t left
the left node in the pair