196 lines
3.6 KiB
C
196 lines
3.6 KiB
C
/* License: AGPLv3 or later. https://www.gnu.org/licenses/licenses.html
|
|
*
|
|
* Exercise 2 - Implementing a heap (Week 3)
|
|
* Name: Manish
|
|
* Student Login: *****
|
|
*
|
|
* Compile as:
|
|
* $ gcc -std=c11 -Wall -o ex2 ex2.c
|
|
*/
|
|
|
|
// assert used only for testing heap property
|
|
// #include <assert.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
int heap[100];
|
|
int size = 0;
|
|
|
|
void makeheap();
|
|
void shiftdown(int index);
|
|
// void shiftup(int index);
|
|
// void swap(int i, int j);
|
|
// int min(int i, int j);
|
|
// void test_heap();
|
|
// int is_bigger_or_equal(int bigger, int smaller);
|
|
|
|
int main(void)
|
|
{
|
|
printf("Enter file name: ");
|
|
char filename[257];
|
|
// Assuming filename/file path won't be longer than 256 characters
|
|
scanf("%256s", filename);
|
|
|
|
FILE* file = fopen(filename, "r");
|
|
if (!file)
|
|
{
|
|
perror(filename);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
// Trailing whitespace to consume all subsequent ' ', \t, \n, \r
|
|
while (fscanf(file, " %d ", &heap[size]) != EOF)
|
|
{
|
|
size++;
|
|
}
|
|
|
|
fclose(file);
|
|
|
|
makeheap();
|
|
|
|
// test_heap();
|
|
|
|
// int upto = min(5, size);
|
|
// Assuming at least 5 integers will be read (else segfault!)
|
|
for (int i = 0; i < 5; i++)
|
|
{
|
|
printf("%d ", heap[i]);
|
|
}
|
|
printf("\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
void makeheap()
|
|
{
|
|
// Shiftdown Method
|
|
int shiftdowns_required = (size / 2)-1;
|
|
for (int i = shiftdowns_required; i >= 0; i--)
|
|
{
|
|
shiftdown(i);
|
|
}
|
|
|
|
// Shiftup method
|
|
/*for (int i = 0; i < size; i++)
|
|
{
|
|
shiftup(i);
|
|
}*/
|
|
}
|
|
|
|
void shiftdown(int index)
|
|
{
|
|
int child;
|
|
int temp; // used for swapping
|
|
// Loop instead of recursion for efficiency
|
|
while (1)
|
|
{
|
|
child = (index * 2) + 1;
|
|
// Reached end of tree
|
|
if (child >= size)
|
|
{
|
|
return;
|
|
}
|
|
// Has only one child
|
|
if (child + 1 >= size)
|
|
{
|
|
}
|
|
// Has both children
|
|
else
|
|
{
|
|
// Pick the bigger child
|
|
if (heap[child] < heap[child + 1])
|
|
{
|
|
child = child + 1;
|
|
}
|
|
}
|
|
if (heap[index] < heap[child])
|
|
{
|
|
// swap
|
|
temp = heap[index];
|
|
heap[index] = heap[child];
|
|
heap[child] = temp;
|
|
|
|
index = child;
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
/*
|
|
void shiftup(int index)
|
|
{
|
|
int parent;
|
|
int temp; // used for swapping
|
|
while (1)
|
|
{
|
|
if (index == 0)
|
|
{
|
|
return;
|
|
}
|
|
parent = (index - 1) / 2;
|
|
if (parent >= 0)
|
|
{
|
|
if (heap[parent] < heap[index])
|
|
{
|
|
// swap
|
|
temp = heap[index];
|
|
heap[index] = heap[parent];
|
|
heap[parent] = temp;
|
|
|
|
index = parent;
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
}*/
|
|
/*
|
|
inline void swap(int i, int j)
|
|
{
|
|
int temp = heap[i];
|
|
heap[i] = heap[j];
|
|
heap[j] = temp;
|
|
}*/
|
|
/*
|
|
inline int min(int i, int j)
|
|
{
|
|
if (i < j)
|
|
{
|
|
return i;
|
|
}
|
|
return j;
|
|
}*/
|
|
/*
|
|
void test_heap()
|
|
{
|
|
int checks_required = (size/2)+1;
|
|
int child;
|
|
for (int i=0; i < checks_required; i++)
|
|
{
|
|
// Left child
|
|
child = (i*2)+1;
|
|
assert(is_bigger_or_equal(i, child));
|
|
// Right child
|
|
assert(is_bigger_or_equal(i, ++child));
|
|
}
|
|
}
|
|
|
|
inline int is_bigger_or_equal(int bigger, int smaller)
|
|
{
|
|
if (bigger < size && smaller < size)
|
|
{
|
|
return (heap[bigger] >= heap[smaller]);
|
|
}
|
|
return 1;
|
|
}
|
|
*/
|