HW04
Source codes for forth assignment
heap.c
Go to the documentation of this file.
1 /**
2  * Functions for creating and working with heap.
3  *
4  * This file contains definitions of heap type and functions designed
5  * to work with it.
6  *
7  * @file heap.c
8  * @author Lubomir Sedlar
9  */
10 #include "heap.h"
11 #include "graph-private.h"
12 
13 #include <assert.h>
14 #include <limits.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 
19 struct heap {
20  size_t size;
21  Node **data;
22 };
23 
24 /**
25  * Swap two elements in an array of nodes and update their index.
26  *
27  * @param arr array representation of the heap
28  * @param i first index
29  * @param j second index
30  */
31 static void swap(Node **arr, int i, int j)
32 {
33  Node *tmp = arr[i];
34  arr[i] = arr[j];
35  arr[j] = tmp;
36  arr[i]->idx = i;
37  arr[j]->idx = j;
38 }
39 
40 /**
41  * Move element at position pos toward root of the tree until it is no longer
42  * lesser than its parent.
43  *
44  * @param arr array representation of the heap
45  * @param pos index of element to fix
46  */
47 static void bubble_up(Node **arr, size_t pos)
48 {
49  if (pos == 0) return;
50  size_t parent_pos = (pos - 1) / 2;
51  while (parent_pos != pos && arr[parent_pos]->dist > arr[pos]->dist) {
52  swap(arr, parent_pos, pos);
53 
54  pos = parent_pos;
55  if (pos == 0) return;
56  parent_pos = (pos - 1) / 2;
57  }
58 }
59 
60 /**
61  * Swap element at position root with its lesser child. Repeat until both
62  * children are greater than this element.
63  *
64  * @param arr array representation of the heap
65  * @param maxidx number of elements
66  * @param root index of subtree root
67  */
68 static void bubble_down(Node **arr, size_t maxidx, size_t root)
69 {
70  size_t child, swp;
71  while ((child = 2 * root + 1) < maxidx) {
72  swp = root;
73 
74  if (arr[root]->dist > arr[child]->dist) {
75  swp = child;
76  }
77  if (child + 1 < maxidx && arr[swp]->dist > arr[child + 1]->dist) {
78  swp = child + 1;
79  }
80  if (swp != root) {
81  swap(arr, root, swp);
82  root = swp;
83  } else {
84  return;
85  }
86  }
87 }
88 
90 {
91  if (!g) return NULL;
92  Heap *h = malloc(sizeof *h);
93  if (!h) {
94  return NULL;
95  }
96  h->data = graph_dup_data(g, &h->size);
97  if (!h->data) {
98  free(h);
99  return NULL;
100  }
101  for (size_t i = 0; i < h->size; i++) {
102  h->data[i]->idx = i;
103  h->data[i]->dist = UINT_MAX;
104  h->data[i]->previous = NULL;
105  }
106  return h;
107 }
108 
110 {
111  return h ? h->size == 0 : true;
112 }
113 
115 {
116  if (!h) return NULL;
117  h->size--;
118  swap(h->data, 0, h->size);
119  bubble_down(h->data, h->size, 0);
120  return h->data[h->size];
121 }
122 
123 void heap_decrease_distance(Heap *h, Node *n, unsigned int val, Node *prev)
124 {
125  if (!h || !n) return;
126  assert(val < n->dist);
127  n->dist = val;
128  n->previous = prev;
129  bubble_up(h->data, n->idx);
130 }
131 
132 void heap_free(Heap *h)
133 {
134  if (h) {
135  free(h->data);
136  }
137  free(h);
138 }
bool heap_is_empty(Heap *h)
Test if a heap is empty.
Definition: heap.c:109
Heap * heap_new_from_graph(Graph *g)
Create new heap with nodes from given graph.
Definition: heap.c:89
void heap_free(Heap *h)
Free all memory used by the heap.
Definition: heap.c:132
struct node Node
Node is an opaque type.
Definition: graph.h:19
Interface for creating and working with heap.
void heap_decrease_distance(Heap *h, Node *n, unsigned int val, Node *prev)
Decrease distance of a certain node.
Definition: heap.c:123
struct heap Heap
Heap is an opaque structure.
Definition: heap.h:19
Node * heap_extract_min(Heap *h)
Remove minimal element from the heap, i.e.
Definition: heap.c:114
struct graph Graph
Graph is an opaque type.
Definition: graph.h:25