Cloned SEACAS for EXODUS library with extra build files for internal package management.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

145 lines
3.8 KiB

2 years ago
/*
* Copyright(C) 1999-2020 National Technology & Engineering Solutions
* of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with
* NTESS, the U.S. Government retains certain rights in this software.
*
* See packages/seacas/LICENSE for details
*/
#include "structs.h"
#include <stdio.h>
#include <stdlib.h>
#define left(i) (2 * (i))
#define right(i) (2 * (i) + 1)
#define parent(i) ((int)((i) / 2))
/* NOTE: heap assumes indices are 1-based. */
/* Note further: All the map arguments and manipulations allow me to */
/* quickly find a particular tag value. This assumes that tags */
/* are integers between 0 and nvals. */
void heapify(struct heap *heap, /* array of vals/tag to make into heap */
int index, /* root of subtree to heapify */
int nvals, /* number of values in array */
int * map /* maps from tag values to heap indices */
)
{
double swap_val; /* temporary storage for swapping values */
double swap_tag; /* temporary storage for swapping values */
int l, r; /* indices of left & right children */
int largest; /* index of largest value */
l = left(index);
r = right(index);
if (l <= nvals && heap[l].val > heap[index].val) {
largest = l;
}
else {
largest = index;
}
if (r <= nvals && heap[r].val > heap[largest].val) {
largest = r;
}
if (largest != index) { /* swap index with largest and recurse */
swap_val = heap[index].val;
swap_tag = heap[index].tag;
heap[index].val = heap[largest].val;
heap[index].tag = heap[largest].tag;
heap[largest].val = swap_val;
heap[largest].tag = swap_tag;
if (map != NULL) { /* update pointers to heap tags */
map[heap[index].tag] = index;
map[heap[largest].tag] = largest;
}
heapify(heap, largest, nvals, map);
}
}
/* Construct a heap from an unordered set of values. */
void heap_build(struct heap *heap, /* array of vals/tag to make into heap */
int nvals, /* number of values in array */
int * map /* maps from tag values to heap indices */
)
{
int i; /* loop counter */
for (i = nvals / 2; i; i--) {
heapify(heap, i, nvals, (int *)NULL);
}
if (map != NULL) {
for (i = 1; i <= nvals; i++) {
map[heap[i].tag] = i;
}
}
}
double heap_extract_max(struct heap *heap, /* array of vals/tag in a heap */
int nvals, /* number of values in array */
int * ptag, /* tag associated with return value */
int * map /* maps from tag values to heap indices */
)
{
double maxval; /* return value */
if (nvals < 1) {
printf("Heap underflow\n");
exit(0);
}
if (map != NULL) { /* turn off map value for extracted tag */
map[heap[1].tag] = 0;
}
maxval = heap[1].val;
*ptag = heap[1].tag;
heap[1].val = heap[nvals].val;
heap[1].tag = heap[nvals].tag;
if (map != NULL) { /* update map value for root */
map[heap[1].tag] = 1;
}
heapify(heap, 1, nvals - 1, map);
return (maxval);
}
void heap_update_val(struct heap *heap, /* array of vals/tag in a heap */
int index, /* index of value to update */
double newval, /* new value to insert */
int * map /* maps from tag values to heap indices */
)
{
int tag; /* tag value associated with updated val */
int dad; /* parent of a tree node */
tag = heap[index].tag;
dad = parent(index);
while (index > 1 && heap[dad].val < newval) {
heap[index].val = heap[dad].val;
heap[index].tag = heap[dad].tag;
if (map != NULL) {
map[heap[index].tag] = index;
}
index = dad;
dad = parent(index);
}
heap[index].val = newval;
heap[index].tag = tag;
if (map != NULL) {
map[tag] = index;
}
}