void heap_minHeapify(int current_index, Heap *heap){ int left_child_index; int right_child_index; int smallest_index = NULL_INDEX; Vector *vector = heap->vector; int heapSize = heap->size; while(smallest_index != current_index){ left_child_index = heap_left(current_index); right_child_index = heap_right(current_index); HeapNode* current = vector_get(current_index, vector); HeapNode* left_child = vector_get(left_child_index, vector); HeapNode* right_child = vector_get(right_child_index, vector); if(left_child_index <= heapSize-1 && (compare(left_child, current, heap) < 0) ) { smallest_index = left_child_index; } else { smallest_index = current_index; } HeapNode* smallest = vector_get(smallest_index, vector); if(right_child_index <= heapSize-1 && (compare(right_child, smallest, heap) < 0) ) { smallest_index = right_child_index; } if(smallest_index != current_index) { vector_swap(current_index, smallest_index, vector); current_index = smallest_index; smallest_index = NULL_INDEX; } } }
/* Dequeue an item from a heap. */ size_t heap_pop(size_t* heap, size_t* m, seq_t** seqs, int (*cmp)(const void*, const void*)) { assert(*m > 0); size_t ans = heap[0]; heap[0] = heap[--(*m)]; size_t tmp, l, r, j, i = 0; while (true) { l = heap_left(i); r = heap_right(i); if (l >= (*m)) break; if (r >= (*m)) { j = l; } else { j = cmp(seqs[heap[l]], seqs[heap[r]]) < 0 ? l : r; } if (cmp(seqs[heap[i]], seqs[heap[j]]) > 0) { tmp = heap[i]; heap[i] = heap[j]; heap[j] = tmp; i = j; } else break; } return ans; }
void heap_maxHeapify(int current_index, Heap* heap){ int left_child_index; int right_child_index; int largest_index = NULL_INDEX; Vector *vector = heap->vector; int heapSize = heap->size; while(largest_index != current_index){ left_child_index = heap_left(current_index); right_child_index = heap_right(current_index); HeapNode* current = vector_get(current_index, vector); HeapNode* left_child = vector_get(left_child_index, vector); HeapNode* right_child = vector_get(right_child_index, vector); if(left_child_index <= heapSize-1 && compare(left_child, current, heap) > 0 ) { largest_index = left_child_index; } else { largest_index = current_index; } HeapNode* largest = vector_get(largest_index, vector); if(right_child_index <= heapSize-1 && compare(right_child, largest, heap) > 0 ) { largest_index = right_child_index; } if(largest_index != current_index) { vector_swap(current_index, largest_index, vector); current_index = largest_index; largest_index = NULL_INDEX; } } }
int heap_extract(Heap *heap, void **data) { void *save, *temp; int ipos, lpos, rpos, mpos; /* Don't allow extraction from empty heap */ if (heap_size(heap) == 0) return -1; /* Extract node at top of heap */ *data = heap->tree[0]; /* Adjust storage used by heap */ save = heap->tree[heap_size(heap) - 1]; if (heap_size(heap) - 1 > 0) { if ((temp = (void **) realloc(heap->tree, (heap_size(heap) - 1) * sizeof(void *))) == NULL) { return -1; } heap->tree = temp; heap->size--; } else { /* Manage the heap when extracting last node */ free(heap->tree); heap->tree = NULL; heap->size = 0; return 0; } /* Copy the last node to the top */ heap->tree[0] = save; /* Heapify the tree by pushing contents of the new top downward */ ipos = 0; while (1) { /* Select child to swap with current node */ lpos = heap_left(ipos); rpos = heap_right(ipos); if (lpos < heap_size(heap) && heap->compare(heap->tree[lpos], heap->tree[ipos]) > 0) mpos = lpos; else mpos = ipos; if (rpos < heap_size(heap) && heap->compare(heap->tree[rpos], heap->tree[mpos]) > 0) mpos = rpos; /* When mpos is ipos, the heap property has been restored */ if (mpos == ipos) break; else { /* Swap contents of current node and select child */ temp = heap->tree[mpos]; heap->tree[mpos] = heap->tree[ipos]; heap->tree[ipos] = temp; /* Move down one level in the tree to continue heapifying */ ipos = mpos; } } return 0; }
void print_heap_item(heap_t *heap, heap_item_t *item, int level, double (*getter)(heap_item_t *item)) { if(item == NULL) { heap_padding('\t', level); puts("~"); } else { print_heap_item(heap, heap_right(heap,item), level + 1, getter); heap_padding('\t', level); printf("%.3lf\n", getter(item)); print_heap_item(heap, heap_left(heap,item), level + 1, getter); } }
void heap_exchange(heap_t *heap, heap_item_t *child, heap_item_t *parent) { heap_item_t *other_child; double other_child_subtree_mass; node_t *child_node, *parent_node; double child_node_mass, parent_node_mass; //double child_subtree_mass, parent_subtree_mass; double parent_subtree_mass; if(heap_left(heap, parent) == child) other_child = heap_right(heap,parent); else if (heap_right(heap, parent) == child) other_child = heap_left(heap,parent); else { fprintf(stderr,"No parent-child relationship between heap items %llu and %llu\n",child->index,parent->index); return; } if(other_child == NULL) { other_child_subtree_mass = 0.; } else { other_child_subtree_mass = other_child->subtree_mass; } child_node = child->node; parent_node = parent->node; child_node_mass = child->node_mass; parent_node_mass = parent->node_mass; //child_subtree_mass = child->subtree_mass; parent_subtree_mass = parent->subtree_mass; parent->node = child_node; child->node = parent_node; parent->node_mass = child_node_mass; child->node_mass = parent_node_mass; //child->subtree_mass = parent_subtree_mass - child_node_mass + parent_node_mass; child->subtree_mass = parent_subtree_mass - child_node_mass - other_child_subtree_mass; }
node_t * heap_item_sample_increment(heap_t *heap, heap_item_t *item, double observed_mass, double uniform_sample, double (*compute_new_mass)(heap_item_t *item)) { node_t *sampled_node; double old_mass; if(heap_left(heap, item) != NULL) { if (uniform_sample < (observed_mass + heap_left(heap, item)->subtree_mass) / heap->total_mass) { sampled_node = heap_item_sample_increment(heap, heap_left(heap, item), observed_mass, uniform_sample,compute_new_mass); return sampled_node; } observed_mass += heap_left(heap, item)->subtree_mass; } observed_mass += item->node_mass; if (uniform_sample < observed_mass / heap->total_mass) { old_mass = item->node_mass; sampled_node = item->node; heap_increase_priority(heap, item, compute_new_mass(item), heap_item_get_node_mass, heap_item_set_node_mass); heap->total_mass += item->node_mass - old_mass; return sampled_node; } if (heap_right(heap, item) != NULL) { sampled_node = heap_item_sample_increment(heap, heap_right(heap, item), observed_mass, uniform_sample, compute_new_mass); return sampled_node; } fprintf(stderr, "Failed to sample a heap node.\n"); return NULL; //should not happen! }
int agile_heap_extract(agile_heap* heap, void** data) { void* save; void* temp; int ipos; int lpos; int rpos; int mpos; if (agile_heap_size(heap)==0) return -1; *data = heap->tree[0]; save = heap->tree[agile_heap_size(heap)-1]; if (agile_heap_size(heap)-1 > 0) { if ((temp=(void**)realloc(heap->tree, (agile_heap_size(heap)-1)*sizeof(void*)))==NULL) return -1; heap->tree = temp; heap->size -= 1; } else { free(heap->tree); heap->tree = NULL; heap->size = 0; return 0; } heap->tree[0] = save; ipos = 0; while (1) { lpos = heap_left(ipos); rpos = heap_right(ipos); if (lpos < agile_heap_size(heap) && heap->compare(heap->tree[lpos],heap->tree[ipos]) > 0) { mpos = lpos; } else { mpos = ipos; } if (rpos < agile_heap_size(heap) && heap->compare(heap->tree[rpos],heap->tree[mpos]) > 0) { mpos = rpos; } if (mpos == ipos) break; temp = heap->tree[mpos]; heap->tree[mpos] = heap->tree[ipos]; heap->tree[ipos] = temp; ipos = mpos; } return 0; }
void heap_percolate_down(heap_t *heap, int index) { void *left, *right, *cur; int l, r, c; c = index; for (;;) { l = heap_left(c); r = heap_right(c); left = array_get(&heap->items, l); right = array_get(&heap->items, r); cur = array_get(&heap->items, c); if (left != NULL && right != NULL) { if (heap->compare(left, right) < 0) { goto left; } else { goto right; } } else if (left != NULL) { goto left; } else if (right != NULL) { goto right; } else { return; } left: if (heap->compare(left, cur) < 0) { array_swap(&heap->items, c, l); c = l; } else { return; } continue; right: if (heap->compare(right, cur) < 0) { array_swap(&heap->items, c, r); c = r; } else { return; } continue; } }
void heapify(collision_heap* heap, short int i){ short int l = heap_left(i), r = heap_right(i), largest; if(l <= heap->length && heap->heap[l].time < heap->heap[i].time){ largest = l; }else{ largest = i; } if(r <= heap->length && heap->heap[r].time < heap->heap[largest].time){ largest = r; } if(largest != i){ collision_data temp; temp = heap->heap[i]; heap->heap[i] = heap->heap[largest]; heap->heap[largest] = temp; heapify(heap, largest); } }
int heap_heapify( heap_t *heap_in, long idx_in ) { byte_t *start = (byte_t*) heap_in->start; int step = heap_in->step; long m = idx_in; const long l = heap_left( idx_in ); const long r = heap_right( idx_in ); if( ( l < heap_in->size ) && heap_in->cmp( start + l * step, start + idx_in * step ) == 1 ) m = l; if( ( r < heap_in->size ) && heap_in->cmp( start + r * step, start + m * step ) == 1 ) m = r; if( m != idx_in ) { if( heap_swap( heap_in, idx_in, m ) != 0 ) return -1; if( heap_heapify( heap_in, m ) != 0 ) return -2; } return 0; }
int heap_extract(Heap *heap, void **data) { void *save, *temp; int ipos, lpos, rpos, mpos; /***************************************************************************** * * * Do not allow extraction from an empty heap. * * * *****************************************************************************/ if (heap_size(heap) == 0) return -1; /***************************************************************************** * * * Extract the node at the top of the heap. * * * *****************************************************************************/ *data = heap->tree[0]; /***************************************************************************** * * * Adjust the storage used by the heap. * * * *****************************************************************************/ save = heap->tree[heap_size(heap) - 1]; if (heap_size(heap) - 1 > 0) { if ((temp = (void **)realloc(heap->tree, (heap_size(heap) - 1) * sizeof (void *))) == NULL) { return -1; } else { heap->tree = temp; } /************************************************************************** * * * Adjust the size of the heap to account for the extracted node. * * * **************************************************************************/ heap->size--; } else { /************************************************************************** * * * Manage the heap when extracting the last node. * * * **************************************************************************/ free(heap->tree); heap->tree = NULL; heap->size = 0; return 0; } /***************************************************************************** * * * Copy the last node to the top. * * * *****************************************************************************/ heap->tree[0] = save; /***************************************************************************** * * * Heapify the tree by pushing the contents of the new top downward. * * * *****************************************************************************/ ipos = 0; lpos = heap_left(ipos); rpos = heap_right(ipos); while (1) { /************************************************************************** * * * Select the child to swap with the current node. * * * **************************************************************************/ lpos = heap_left(ipos); rpos = heap_right(ipos); if (lpos < heap_size(heap) && heap->compare(heap->tree[lpos], heap-> tree[ipos]) > 0) { mpos = lpos; } else { mpos = ipos; } if (rpos < heap_size(heap) && heap->compare(heap->tree[rpos], heap-> tree[mpos]) > 0) { mpos = rpos; } /************************************************************************** * * * When mpos is ipos, the heap property has been restored. * * * **************************************************************************/ if (mpos == ipos) { break; } else { /*********************************************************************** * * * Swap the contents of the current node and the selected child. * * * ***********************************************************************/ temp = heap->tree[mpos]; heap->tree[mpos] = heap->tree[ipos]; heap->tree[ipos] = temp; /*********************************************************************** * * * Move down one level in the tree to continue heapifying. * * * ***********************************************************************/ ipos = mpos; } } return 0; }
int minheap_get_first (heap_t *heap, elem_t *elem) { elem_t ret; ofs_t loc, end; key_t key; if (heap->cnt == 0) return -ENOENT; /* this is what we are returning */ ret = heap->data[0]; /* move the last element into the first location, shrinking the heap * by one */ heap->data[0] = heap->data[--heap->cnt]; heap->data[heap->cnt] = -1; /* now move down fixing the order */ loc = 0; key = elem_key (heap->data[loc]); end = (heap->cnt-1)/2; pd ("cnt = %d\n", heap->cnt); pd ("end = %d\n", end); while (loc < end) { ofs_t min_ofs; ofs_t left_ofs = heap_left (heap, loc); ofs_t right_ofs = heap_right (heap, loc); key_t min_key; key_t left_key = elem_key (heap->data[left_ofs]); key_t right_key = elem_key (heap->data[right_ofs]); pd ("loc = @%d [%d]\n", loc, key); pd ("left = @%d [%d]\n", left_ofs, left_key); pd ("right = @%d [%d]\n", right_ofs, right_key); if (left_key < right_key) { min_key = left_key; min_ofs = left_ofs; } else { min_key = right_key; min_ofs = right_ofs; } /* parent must be smaller */ if (key < min_key) goto done; /* if not then swap the elements */ pd (">> swap = @%d [%d] <-> @%d [%d]\n", loc, key, min_ofs, min_key); heap_swap (heap, loc, min_ofs); /* move to swapped child */ loc = min_ofs; //key = min_key; pd ("loc = @%d [%d]\n", loc, key); pd ("\n"); } /* it's possible that we have a node on our path with only one child; * in this case the tree count is even and if it is then we must only * compare to the left subtree */ if ((loc == end) && !(heap->cnt & 1)) { ofs_t left_ofs = heap_left (heap, loc); key_t left_key; pd ("bonus\n"); if (left_ofs == OFS_INVAL) { pd ("...bailed\n"); goto done; } left_key = elem_key (heap->data[left_ofs]); pd ("loc = @%d [%d]\n", loc, key); pd ("left = @%d [%d]\n", left_ofs, left_key); /* parent must be smaller */ if (key < left_key) goto done; pd (">> swap = @%d [%d] <-> @%d [%d]\n", loc, key, left_ofs, left_key); /* if not then swap the elements */ heap_swap (heap, loc, left_ofs); } done: *elem = ret; return 0; }
int heap_extract(Heap *heap, void **data) { void *save, *temp; int ipos, lpos, rpos, mpos; if (heap_size(heap) == 0) return -1; *data = heap->tree[0]; save = heap->tree[heap_size(heap) - 1]; /* * Adjust heap storage. There are two cases: * * 1. Only one node left * 2. More than one node left */ /* Case 1: Only one left */ if (heap_size(heap) - 1 == 0) { free(heap->tree); heap->tree = NULL; heap->size = 0; return 0; } /* Case 2: More than 1 left */ if ((temp = (void **)realloc(heap->tree,(heap_size(heap) - 1) * sizeof(void *))) == NULL) return -1; heap->tree = temp; heap->size--; /* * Copy last node to top and then heapify */ heap->tree[0] = save; ipos = 0; while (1) { lpos = heap_left(ipos); rpos = heap_right(ipos); /* * Find position with max value. First check left child... */ if (lpos < heap_size(heap) && heap->compare(heap->tree[lpos], heap->tree[ipos]) > 0) mpos = lpos; else mpos = ipos; /* ...then check right child */ if (rpos < heap_size(heap) && heap->compare(heap->tree[rpos], heap->tree[mpos]) > 0) mpos = rpos; /* If the max position is the insert position, we're done. */ if (mpos == ipos) break; /* otherwise, keep going */ temp = heap->tree[mpos]; heap->tree[mpos] = heap->tree[ipos]; heap->tree[ipos] = temp; ipos = mpos; } return 0; }
int heap_extract(Heap *heap, void **data) { void *save, *tmp; int ipos, lpos, rpos, mpos; if (heap->size == 0) { return -1; } *data = heap->tree[0]; save = heap->tree[heap->size - 1]; if (heap->size - 1 > 0) { tmp = (void **)realloc(heap->tree, (heap->size - 1) * sizeof(void *)); if (tmp) { heap->tree = tmp; } else { return -1; } heap->size--; } else { free(heap->tree); heap->tree = NULL; heap->size = 0; return 0; } heap->tree[0] = save; ipos = 0; while (1) { lpos = heap_left(ipos); rpos = heap_right(ipos); if (lpos < heap->size && heap->compare(heap->tree[lpos], heap->tree[ipos]) > 0) { mpos = lpos; } else { mpos = ipos; } if (rpos < heap->size && heap->compare(heap->tree[rpos], heap->tree[mpos]) > 0) { mpos = rpos; } if (mpos == ipos) { break; } else { tmp = heap->tree[mpos]; heap->tree[mpos] = heap->tree[ipos]; heap->tree[ipos] = tmp; ipos = mpos; } } return 0; }