Guest User

Untitled

a guest
May 26th, 2018
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.79 KB | None | 0 0
  1. #include <assert.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <math.h>
  5. #include <stdbool.h>
  6. #include <unistd.h>
  7.  
  8. typedef struct {
  9. unsigned short int fuelAmt, flightNum;
  10. } aircraft_t;
  11.  
  12. typedef struct {
  13. unsigned int arraysize, heapsize;
  14. aircraft_t *array;
  15. } deap_t;
  16.  
  17. aircraft_t get_min(deap_t deap) {
  18. return deap.array[2];
  19. }
  20.  
  21. aircraft_t get_max(deap_t deap) {
  22. if (deap.heapsize > 2)
  23. return deap.array[3];
  24. else
  25. return get_min(deap);
  26. }
  27.  
  28. int row_starts(int i) {
  29. return pow(2, (int) log2(i));
  30. }
  31.  
  32. int swap(deap_t *flights, int from, int to) {
  33. /* Use the empty 0 spot for temporary storage */
  34. flights->array[0] = flights->array[to];
  35. flights->array[to] = flights->array[from];
  36. flights->array[from] = flights->array[0];
  37.  
  38. return to;
  39. }
  40.  
  41. int cousin(deap_t deap, int i, bool try_parent) {
  42. int midpoint = row_starts(i) * 1.5;
  43. int cousin;
  44.  
  45. if (i < midpoint)
  46. cousin = i - row_starts(i) + midpoint;
  47. else
  48. cousin = i + row_starts(i) - midpoint;
  49.  
  50. if (try_parent && cousin > deap.heapsize)
  51. cousin /= 2; /* If there's no node there, use the parent */
  52.  
  53. if (cousin == 1)
  54. cousin = 2; /* Special-case for when we accidentally choose 1 */
  55.  
  56. return cousin;
  57. }
  58.  
  59. void trickle_up(deap_t *deap, int from_index) {
  60. if (from_index/2 < 2)
  61. return;
  62. if (cousin(*deap, from_index, false) > from_index) {
  63. /* this is the min-heap side */
  64. if (deap->array[from_index].fuelAmt < deap->array[from_index/2].fuelAmt)
  65. trickle_up(deap, swap(deap, from_index, from_index/2));
  66. }
  67. else {
  68. /* max-heap side of the deap */
  69. if (deap->array[from_index].fuelAmt > deap->array[from_index/2].fuelAmt)
  70. trickle_up(deap, swap(deap, from_index, from_index/2));
  71. }
  72. }
  73.  
  74. int trickle_down(deap_t *deap, int from_index) {
  75. aircraft_t leftchild, rightchild;
  76. leftchild = deap->array[from_index*2];
  77. rightchild = deap->array[from_index*2 + 1];
  78.  
  79. if (from_index*2 > deap->heapsize)
  80. return from_index;
  81. if (cousin(*deap, from_index, false) > from_index) {
  82. /* this is the min-heap side */
  83. if (leftchild.fuelAmt < rightchild.fuelAmt) {
  84. if (deap->array[from_index].fuelAmt > leftchild.fuelAmt)
  85. return trickle_down(deap, swap(deap, from_index, from_index*2));
  86. }
  87. else if (deap->array[from_index].fuelAmt > rightchild.fuelAmt)
  88. return trickle_down(deap, swap(deap, from_index, from_index*2 + 1));
  89. }
  90. else {
  91. /* max-heap side of the deap */
  92. if (leftchild.fuelAmt > rightchild.fuelAmt) {
  93. if (deap->array[from_index].fuelAmt < leftchild.fuelAmt)
  94. return trickle_down(deap, swap(deap, from_index, from_index*2));
  95. }
  96. else if (deap->array[from_index].fuelAmt < rightchild.fuelAmt)
  97. return trickle_down(deap, swap(deap, from_index, from_index*2 + 1));
  98. }
  99. return from_index;
  100. }
  101.  
  102. bool on_correct_side(deap_t deap, int thisi) {
  103. int cousini = cousin(deap, thisi, false);
  104. int cousinp = cousin(deap, thisi, true);
  105. int cousinv = deap.array[cousinp].fuelAmt;
  106. int thisv = deap.array[thisi].fuelAmt;
  107.  
  108. if (cousini > thisi && cousinv >= thisv)
  109. return true;
  110. else if (cousini < thisi && cousinv <= thisv)
  111. return true;
  112. else
  113. return false;
  114. }
  115.  
  116. void insert(deap_t *flights, aircraft_t new) {
  117. printf("Inserting %d\n", new.fuelAmt);
  118. flights->array[++(flights->heapsize)] = new;
  119. if (!on_correct_side(*flights, flights->heapsize))
  120. swap(flights, flights->heapsize, cousin(*flights, flights->heapsize, true));
  121.  
  122. trickle_up(flights, cousin(*flights, flights->heapsize, true));
  123. }
  124.  
  125. aircraft_t pop_min(deap_t *deap) {
  126. /* I think it's possible this solved the issues with < 5 elements and problems
  127. shown in class, but I'm not sure. I forget how they happened. */
  128. int newindex;
  129.  
  130. deap->array[1] = deap->array[2]; /* save for later. */
  131. deap->heapsize--; /* The last spot on the deep was just dropped */
  132.  
  133. /* Trickle down the "empty" spot, pretend it's worth infinity, go bottom */
  134.  
  135. deap->array[2].fuelAmt = -1; /* unsigned, we just overflowed to max. */
  136. newindex = trickle_down(deap, 2);
  137.  
  138. /* Now we go and replace that element with our dropped one from earlier */
  139. deap->array[newindex] = deap->array[deap->heapsize + 1];
  140. trickle_up(deap, newindex);
  141.  
  142. return deap->array[1];
  143. }
  144.  
  145. aircraft_t pop_max(deap_t *deap) {
  146. /* Just like min. I could probably combine these functions. */
  147. int newindex;
  148.  
  149. deap->array[1] = deap->array[3]; /* save for later. 0 and 1 unused. */
  150. deap->heapsize--; /* The last spot on the deep was just dropped */
  151.  
  152. /* Trickle down the "empty" spot, pretend it's worth nothing, goes bottom */
  153.  
  154. deap->array[3].fuelAmt = 0;
  155. newindex = trickle_down(deap, 3);
  156.  
  157. /* Now we go and replace that element with our dropped one from earlier */
  158. deap->array[newindex] = deap->array[deap->heapsize + 1];
  159. trickle_up(deap, newindex);
  160.  
  161. return deap->array[1];
  162. }
  163.  
  164.  
  165. void printheap(deap_t flights) {
  166. unsigned short int i;
  167. for (i = 2; i <= flights.heapsize; i++) {
  168. if ((i & (i - 1)) == 0) /* Check if power of two. */
  169. puts("\n");
  170.  
  171. printf("%3d ", flights.array[i].fuelAmt);
  172. }
  173. }
  174.  
  175. void init_deap(deap_t *empty, int size) {
  176. empty->array = calloc(size, sizeof(aircraft_t));
  177. empty->arraysize = size;
  178. empty->heapsize = 1;
  179. }
  180.  
  181. int main(int argc, char *argv[]) {
  182. FILE *input;
  183. bool verbose = false;
  184. char *datafile = "DEAPdataFileSmall";
  185. short int c;
  186.  
  187. char opcode;
  188. aircraft_t newplane;
  189. deap_t flights;
  190.  
  191. /* getopt is a nice helper to parse cli parameters. */
  192. while ((c = getopt(argc, argv, "vi:")) != -1) {
  193. switch (c) {
  194. case 'v':
  195. verbose = true;
  196. break;
  197. case 'i':
  198. datafile = optarg;
  199. break;
  200. default:
  201. puts("usage: [-v] [-i INPUTFILE]");
  202. exit(1);
  203. }
  204. }
  205.  
  206. init_deap(&flights, 5000);
  207.  
  208. input = fopen(datafile, "r");
  209. assert(input != NULL);
  210.  
  211. while (opcode != EOF) {
  212. switch(opcode = getc(input)) {
  213. case 'i':
  214. fscanf(input, " %hu %hu", &newplane.fuelAmt, &newplane.flightNum);
  215. insert(&flights, newplane);
  216. printheap(flights);
  217. puts("\n-----");
  218. break;
  219.  
  220. case 'L':
  221. printf("Popped min. %hu\n", pop_min(&flights).fuelAmt);
  222. printheap(flights);
  223. break;
  224.  
  225. case 'D':
  226. printf("Popped max. %hu\n", pop_max(&flights).fuelAmt);
  227. printheap(flights);
  228. break;
  229. }
  230. }
  231.  
  232. fclose(input);
  233.  
  234. free(flights.array);
  235. return 1;
  236. }
Add Comment
Please, Sign In to add comment