Having trouble with Downheap Algorithm via array implementation - c

I am currently trying to sort my array of keys using the Down-heap algorithm. However, when I display my newly sorted array, new numbers appear and the order doesn't seem right. I cannot tell if something is wrong with my algorithm or if I'm not using the proper conditions for this sorting algorithm.
My job is to sort an array of 20 keys.
The Code:
/* Downheap sorting algorithm */
for(i=0; i<20; i++)
{
j = i + 1;
/* If parent is less than both children */
if(key[j] < key[2*j] && key[j] < key[(2*j)+1])
{
/* Check which child is smallest */
if(key[2*j] < key[(2*j)+1])
{
/* Parent is assigned smallest node */
swap(&key[j],&key[2*j]);
}
else{swap(&key[j],&key[(2*j)+1]);}
}
/* If parent is less than left child */
else if(key[j] < key[2*j])
{
swap(&key[j],&key[2*j]);
}
/* If parent is less than right child */
else if(key[j] < key[(2*j)+1])
{
swap(&key[j],&key[(2*j)+1]);
}
}
The Swap Function:
void swap(int *parent, int *child)
{
int temp;
temp = *child;
*child = *parent;
*parent = temp;
}
Array of keys before sorting:
54,90,137,260,185,65,208,139,114,176,186,77,137,139,178,57,203,110,80,127
Array of keys after sorting once:
54,137,185,260,114,77,208,178,110,176,186,65,137,139,139,64,203,90,84,127
64 was not there before. Where is 57? 80 has disappeared and where did 84 come from?
Any help would be much appreciated!

If you have an array of 20 numbers they will usually be key[0]..key[19], and with a heap you will need to consider the possibility that one or more of the children of a heap element do not exist because their array positions would be off the edge of the array. With heap numbers 0..19 then the children of element i would be at 2i+1 and 2i+2, so 0 has children 1 and 2, 1 has children 3 and 4... 8 has children 17 and 18, but 9 has only one child at 19 and 10 has no children at all.
Are you expecting Downheap to do all of the work of sorting? Normally, as explained at http://en.wikipedia.org/wiki/Heapsort, Downheap is part but not all of Heapsort.

By "DownHeap" i am asuming you mean Min-Heap
Algo for min heap :
public void insert(Comparable x)
{
if(size == heap.length - 1) doubleSize();
//Insert a new item to the end of the array
int pos = ++size;
//Percolate up
for(; pos > 1 && x.compareTo(heap[pos/2]) < 0; pos = pos/2 )
heap[pos] = heap[pos/2];
heap[pos] = x;
}'
Check This Link To understand min heapmin heap

Related

using new array to store the sorted values in heap sort

I am currently studying about the algorithm about heap sorts, I wonder if it is possible to make a heapsort function that stores the sorted value in a new array (aside from the initial array where the unsorted values is stored) and not do anything to the initial array?
if you delete in heap sort, the root will switch with the last element right? so the last element will now have the address of the root, and the previous root will be placed in the last index/address in the array. After swapping the values, the size of the array will be decremented and the current address of the previous root will now not be considered as part of the array (because of decrease in array size).
So, what I want to know is a heapsort function that takes the initial array as the parameter. Im wondering if it is possible to take the element that will be deleted in the initial array and storing it in the new array in min heap order without doing anything to the initial array.
this is the code that Im studying from a website, im copying it here so that you can all see what im into
#include <stdio.h>
#include <stdlib.h>
typedef struct MinHeap MinHeap;
struct MinHeap {
int* arr;
// Current Size of the Heap
int size;
// Maximum capacity of the heap
int capacity;
};
int parent(int i) {
// Get the index of the parent
return (i - 1) / 2;
}
int left_child(int i) {
return (2*i + 1);
}
int right_child(int i) {
return (2*i + 2);
}
int get_min(MinHeap* heap) {
// Return the root node element,
// since that's the minimum
return heap->arr[0];
}
MinHeap* init_minheap(int capacity) {
MinHeap* minheap = (MinHeap*) calloc (1, sizeof(MinHeap));
minheap->arr = (int*) calloc (capacity, sizeof(int));
minheap->capacity = capacity;
minheap->size = 0;
return minheap;
}
MinHeap* insert_minheap(MinHeap* heap, int element) {
// Inserts an element to the min heap
// We first add it to the bottom (last level)
// of the tree, and keep swapping with it's parent
// if it is lesser than it. We keep doing that until
// we reach the root node. So, we will have inserted the
// element in it's proper position to preserve the min heap property
if (heap->size == heap->capacity) {
fprintf(stderr, "Cannot insert %d. Heap is already full!\n", element);
return heap;
}
// We can add it. Increase the size and add it to the end
heap->size++;
heap->arr[heap->size - 1] = element;
// Keep swapping until we reach the root
int curr = heap->size - 1;
// As long as you aren't in the root node, and while the
// parent of the last element is greater than it
while (curr > 0 && heap->arr[parent(curr)] > heap->arr[curr]) {
// Swap
int temp = heap->arr[parent(curr)];
heap->arr[parent(curr)] = heap->arr[curr];
heap->arr[curr] = temp;
// Update the current index of element
curr = parent(curr);
}
return heap;
}
MinHeap* heapify(MinHeap* heap, int index) {
// Rearranges the heap as to maintain
// the min-heap property
if (heap->size <= 1)
return heap;
int left = left_child(index);
int right = right_child(index);
// Variable to get the smallest element of the subtree
// of an element an index
int smallest = index;
// If the left child is smaller than this element, it is
// the smallest
if (left < heap->size && heap->arr[left] < heap->arr[index])
smallest = left;
// Similarly for the right, but we are updating the smallest element
// so that it will definitely give the least element of the subtree
if (right < heap->size && heap->arr[right] < heap->arr[smallest])
smallest = right;
// Now if the current element is not the smallest,
// swap with the current element. The min heap property
// is now satisfied for this subtree. We now need to
// recursively keep doing this until we reach the root node,
// the point at which there will be no change!
if (smallest != index)
{
int temp = heap->arr[index];
heap->arr[index] = heap->arr[smallest];
heap->arr[smallest] = temp;
heap = heapify(heap, smallest);
}
return heap;
}
MinHeap* delete_minimum(MinHeap* heap) {
// Deletes the minimum element, at the root
if (!heap || heap->size == 0)
return heap;
int size = heap->size;
int last_element = heap->arr[size-1];
// Update root value with the last element
heap->arr[0] = last_element;
// Now remove the last element, by decreasing the size
heap->size--;
size--;
// We need to call heapify(), to maintain the min-heap
// property
heap = heapify(heap, 0);
return heap;
}
MinHeap* delete_element(MinHeap* heap, int index) {
// Deletes an element, indexed by index
// Ensure that it's lesser than the current root
heap->arr[index] = get_min(heap) - 1;
// Now keep swapping, until we update the tree
int curr = index;
while (curr > 0 && heap->arr[parent(curr)] > heap->arr[curr]) {
int temp = heap->arr[parent(curr)];
heap->arr[parent(curr)] = heap->arr[curr];
heap->arr[curr] = temp;
curr = parent(curr);
}
// Now simply delete the minimum element
heap = delete_minimum(heap);
return heap;
}
void print_heap(MinHeap* heap) {
// Simply print the array. This is an
// inorder traversal of the tree
printf("Min Heap:\n");
for (int i=0; i<heap->size; i++) {
printf("%d -> ", heap->arr[i]);
}
printf("\n");
}
void free_minheap(MinHeap* heap) {
if (!heap)
return;
free(heap->arr);
free(heap);
}
int main() {
// Capacity of 10 elements
MinHeap* heap = init_minheap(10);
insert_minheap(heap, 40);
insert_minheap(heap, 50);
insert_minheap(heap, 5);
print_heap(heap);
// Delete the heap->arr[1] (50)
delete_element(heap, 1);
print_heap(heap);
free_minheap(heap);
return 0;
}
EDIT:
if what im saying about is possible, can you please show me how? so that i can see and study the code. many thanks.

Find all unsorted pairs in partially sorted array

I have to find (or atleast count) all pairs of (not necessarily adjacent) unsorted elements in a partially sorted array.
If we assume the sorting to be ascending, the array [1 4 3 2 5] has the following unsorted pairs: (4, 3), (3, 2) and (4, 2).
I'm thinking of an algorithm that works along the lines of insertion sort, as insertion sort tends to compare every new element with all elements which are misplaced with respect to the new element.
Edit: While posting the question, I didn't realise that finding the pairs would have a higher time complexity than counting them. Is there a better possible algorithm that just counts how many such pairs exist?
It depends a little bit on what you mean exactly by "partially sorted" - One could argue that every array is partially sorted to some degree.
Since this algorithm has worst-case complexity O(n^2) anyway (consider the input sorted in descending order), you might as well go down the straight-forward route:
ret = []
for i in range(len(array)):
for j in range(i, len(array)):
if array[i] > array[j]:
ret.append((array[i], array[j]))
return ret
This works very well for random arrays.
However, I suppose what you have in mind is more something that there are larger stretches inside the array where the numbers are sorted but that that's not the case for the array as a whole.
In that case, you can save a bit of time over the naive approach above by first identifying those stretches - this can be done in a linear pass. Once you have them, you only have to compare these stretches with each other, and you can use binary search for that (since the stretches are in sort order).
Here's a Python implementation of what I have in mind:
# find all sorted stretches
stretches = []
begin = 0
for i in range(1, len(array)):
if array[i-1] > array[i]:
stretches.append(array[begin:i])
begin = i
if i+1 > begin:
stretches.append(array[begin:])
# compare stretches
ret = []
for i in range(len(stretches)):
stretchi = stretches[i]
stretchi_rev = None
for j in range(i+1, len(stretches)):
stretchj = stretches[j]
if stretchi[-1] > stretchj[0]:
if stretchi_rev is None:
stretchi_rev = list(reversed(stretchi))
hi = len(stretchj)
for x in stretchi_rev:
i = bisect.bisect_left(stretchj, x, 0, hi)
if i == 0:
break
else:
for y in stretchj[:i]:
ret.append((x, y))
hi = i
return ret
For random arrays, this will be slower than the first approach. But if the array is big, and the amount of partially sorted portions is high enough, this algorithm will at some point starting to beat the brute-force search.
As suggested by #SomeDude in the comments, if you just need to count pairs there's an O(nlogn) solution based on building a binary search tree. There are some subtleties involved - we need to keep track of the number of duplicates (ic) at each node, and for performance reasons we also keep track of the number of right children (rc).
The basic scheme for inserting a value v intro the tree rooted at node n is:
def insert(n, v)
if v < n.data
count = 1 + n.ic + n.rc
if n.left is null
n.left = node(v)
return count
return count + insert(n.left, v)
else if v > n.data
if n.right is null
n.right = node(v)
n.rc = 1
return 0
n.rc += 1
return insert(n.right, v)
else // v == n.data
n.ic += 1
return n.rc
And here's some functioning Java code (Ideone):
static int pairsCount(Integer[] arr) {
int count = 0;
Node root = new Node(arr[0]);
for(int i=1; i<arr.length; i++)
count += insert(root, arr[i]);
return count;
}
static int insert(Node n, int v) {
if(v < n.value) {
int count = 1 + n.rc + n.ic;
if(n.left == null) {
n.left = new Node(v);
return count;
}
return count + insert(n.left, v);
}
else if(v > n.value) {
if(n.right == null) {
n.right = new Node(v);
n.rc = 1;
return 0;
}
n.rc += 1;
return insert(n.right, v);
}
else {
n.ic += 1;
return n.rc;
}
}
static class Node {
int value;
Node left, right;
int rc; // right children count
int ic; // duplicate count
Node(int value) {
this.value = value;
}
}
Test:
Integer[] arr = {1, 4, 3, 2, 5};
System.out.println(pairsCount(arr));
Output:
3

What is more effective (in particular, in C): moving an array element or deleting it and creating it in a new place?

I am learning the C language and as I am learning it, I encountered the question.
How best to make the next change in the array:
I have an array of structs. Array's size changes quite frequently. In particular, I need to remove the last element of it and create an new element with [0] index, changing the content of the structure (the structures contain coordinates, I need to change these coordinates).
Would it make any difference if I moved the last element to the place of [0] index, moving the array's elements forward, e. g., using memmove() function instead of deleting the last element and creating a new one with [0] index (also, as I understand I need here too "compress" the array on 1 element to the forward using the memmove() function?)?
Or does it not matter? Maybe there is a way to do it better (in particular, I am interested in C or C++ (more specifically, C subset)).
If you need any clarification, please let me know and I will try to explain it in more detail.
Thank you for your attention!
UPDATE (for better understanding).
Array contains structs containing 2 integer variables x and y (coords).
What should I do with "array":
To be able to remove the last element - this will have to be done often.
Parallel to (1), I need to add a new element to the begin - "the head". That’s the crux of the question - I can just change the coordinates of the last element, move it to the beginning. Either create a new element with a new structure and simply remove the last element.
Also sometimes "array" will increase, i.e. a new structure will be added. This happens regardless of (1) and (2) points.
What you describe – frequent operations at both ends of an array – is a typical use case for a double-ended queue, or deque. The C++ standard library has std::deque<T>. In C, you can implement a deque as a circular buffer.
Imagine you have an array of a fixed size. Apart from the size, the array also has a length, the number of valid values in the array. You can now push and pop elements at the end:
[. . . . . . . .] length = 0
[0 . . . . . . .] push(arr, 0) arr[length++] = 0
[0 1 . . . . . .] push(arr, 1) arr[length++] = 1
[0 1 2 . . . . .] push(arr, 2) arr[length++] = 2
[0 1 . . . . . .] x = pop(arr) x = arr[--length]0
Now, if you want to add or remove element at the front, you have to shift the remaining elements. A circular buffer does something different: When you insert an element at the start, you fill the "gap" (the dots) from the right and you keep the start index. That way, the array wraps:
[0 1 2 3 4 . . .] ^: start index
^ // seen as:
[0 1 2 3 4 . . a] unshift(arr, a) // [a, 0, 1, 2, 3, 4]
^
[0 1 2 3 4 . b a] unshift(arr, b) // [b, a, 0, 1, 2, 3, 4]
^
[0 1 2 3 4 . . a] x = shift(arr) // == b
^
In this buffer, you will not access the elements directly with arr[i]. You need access functions that will do the wrappig logic behind the scenes.
You can make the deque allocate more memory as it grows. An example implementation is below.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct Queue Queue;
typedef unsigned Item;
#define enforce(COND, MSG) \
if (COND); else exit((fprintf(stderr, "Fatal :" MSG "\n"), 1))
struct Queue {
size_t length;
size_t size;
size_t start;
Item *item;
};
/*
* Create queue object
*/
Queue *queue_create(void)
{
Queue *q = calloc(1, sizeof(*q));
return q;
}
/*
* Destroy queue object
*/
void queue_destroy(Queue *q)
{
if (q) {
free(q->item);
free(q);
}
}
/*
* Internal: re-allocate
*/
static void queue_grow(Queue *q)
{
if (q->length >= q->size) {
size_t old_size = q->size;
q->size = (old_size) ? 2 * old_size : 16;
q->item = realloc(q->item, q->size * sizeof(*q->item));
enforce(q->item, "Allocation failed!");
memcpy(q->item + q->start + old_size,
q->item + q->start,
(old_size - q->start) * sizeof(*q->item));
q->start += old_size;
}
}
/*
* Add an item at the end
*/
void queue_push(Queue *q, Item item)
{
queue_grow(q);
q->item[(q->start + q->length++) % q->size] = item;
}
/*
* Remove the item at the end
*/
Item queue_pop(Queue *q)
{
if (q->length) {
return q->item[(q->start + --q->length) % q->size];
}
enforce(0, "Queue underflow!");
return 0;
}
/*
* Add an item at the front
*/
void queue_unshift(Queue *q, Item item)
{
queue_grow(q);
if (q->start) {
q->start--;
} else {
q->start = q->size - 1;
}
q->length++;
q->item[q->start] = item;
}
/*
* Remove the item from the front
*/
Item queue_shift(Queue *q)
{
Item item = q->item[q->start];
q->length--;
q->start++;
if (q->start == q->size) q->start = 0;
return item;
}
/*
* Get the item at index (Neg. index counts from the end)
*/
Item queue_at(const Queue *q, long long index)
{
if (index < 0) index += q->length;
enforce(0 <= index && index < q->length, "Bad index!");
return q->item[(q->start + index) % q->size];
}
/*
* Get a pointer to the item at index
*/
Item *queue_ref_at(const Queue *q, long long index)
{
if (index < 0) index += q->length;
if (index < 0 || index >= q->length) return 0;
return (Item *) &q->item[(q->start + index) % q->size];
}
/*
* Get the length of the queue
*/
size_t queue_length(const Queue *q)
{
return q->length;
}
/*
* (Rather silly) Example
*/
int main(void)
{
Queue *q = queue_create();
unsigned sum = 0;
unsigned i;
for (i = 0; i < 1000; i++) {
queue_push(q, i);
}
for (i = 0; i < 100; i++) {
queue_unshift(q, -(1 + i));
}
printf("start: %d\n", queue_at(q, 0)); // -100
printf("end: %d\n", queue_at(q, -1)); // 999
unsigned *ref = queue_ref_at(q, -1);
if (ref) *ref = 10000;
printf("end: %d\n", queue_pop(q));
while (queue_length(q)) {
sum += queue_shift(q);
}
printf("sum: %d\n", sum);
queue_destroy(q);
return 0;
}

Fastest way to remove huge number of elements from an array in C

I have dynamic array that contains thousands of elements or even more, in order not to consume a large size of memory, I can remove unwanted elements from it (i.e elements have been used and no need for them any more) so from the beginning I can allocate a smaller memory size by estimating the maximum required size after removing the elements each time.
I use this way but it takes a very very long time to finish, sometime takes 30 minutes!
int x, y ;
for (x = 0 ; x<number_of_elements_to_remove ; x++){
for (y = 0 ; y<size_of_array; y++ ){
array[y] = array[y+1];
}
}
Is there a faster way than this?
Instead of removing elements one at a time, with two loops making for an O(n2) solution, you can make a single loop, with a single read and a single write index. Go through the array, copying items as you go:
int rd = 0, wr = 0;
while (rd != size_of_array) {
if (keep_element(array[rd])) {
array[wr++] = array[rd];
}
rd++;
}
At the end of the loop wr is the number of elements kept in the array.
as I noticed you want to only delete elements from the start of the array, try this:
int x;
for(x = 0 ; x< size_of_array - number_of_elements_to_remove; x++)
array[x] = array[number_of_elements_to_remove + x];
this way you're using one for loop which reduces the complexity alot
It seems you essentially do
int y;
for (y = 0; y<size_of_array; y++){
array[y] = array[y+numbre_of_elements_to_remove];
}
The above should be faster, but there are still some caveats / problems with your code (e.g., access beyond the end od the array).
Here is the code to defragment the array.
int sparse_to_compact(int*arr, int total, int*is_valid) {
int i = 0;
int last = total - 1;
// trim the last invalid elements
for(; last >= 0 && !is_valid[last]; last--); // trim invalid elements from last
// now we keep swapping the invalid with last valid element
for(i=0; i < last; i++) {
if(is_valid[i])
continue;
arr[i] = arr[last]; // swap invalid with the last valid
last--;
for(; last >= 0 && !is_valid[last]; last--); // trim invalid elements
}
return last+1; // return the compact length of the array
}
I copied the code from this answer.
I think more efficient way is to use a link-list of buckets. And the buckets are managed by bit-string memory manager. It is like the following,
struct elem {
uint32_t index; /* helper to locate it's position in the array */
int x; /* The content/object kept in the array */
}
Suppose, our array content is int and it is encapsulated in a structure named struct elem.
enum {
MAX_BUCKET_SIZE = 1024,
MAX_BITMASK_SIZE = (MAX_BUCKET_SIZE + 63) >> 6,
};
struct bucket {
struct bucket*next; /* link to the next bucket */
uint64_t usage[MAX_BITMASK_SIZE]; /* track memory usage */
struct elem[MAX_BUCKET_SIZE]; /* the array */
};
A bucket is defined as an array of struct elem and usage mask.
struct bucket_list {
struct bucket*head; /* dynamically allocated bucket */
}container;
And a bucket list is a linked list containing all the buckets.
So we need to write memory manager code.
At first we need new bucket to be allocated when needed.
struct bucket*bk = get_empty_bucket(&container);
if(!bk) { /* no empty bucket */
/* allocate a bucket */
struct bucket*bk = (struct bucket*)malloc(sizeof(struct bucket));
assert(bk);
/* cleanup the usage flag */
memset(bk->usage, 0, sizeof(bk->usage));
/* link the bucket */
bk->next = container.head;
container.head = bk;
}
Now as we have the bucket we need to set the value in the array when needed.
for(i = 0; i < MAX_BITMASK_SIZE; i++) {
uint64_t bits = ~bk.usage[i];
if(!bits) continue; /* no space */
/* get the next empty position */
int bit_index = _builtin_ctzl(bits);
int index = (i<<6)+bit_index;
/* set the array value */
bk->elem[index].index = index;
bk->elem[index].x = 34/* my value */;
bk.usage[i] |= 1<<bit_index; /* mark/flag the array element as used */
}
Deleting the array elements is easy as to mark them unused. Now when all the elements in a bucket is unused we can delete the bucket from the link-list.
We can sometimes defragment buckets or optimize them to fit in smaller space. Otherwise when we assign new elements we can select more crowded buckets over less crowded one. When we delete we can swap the element of less crowded one into more crowded one.
It is possible to delete elements of array in efficient way,
int remove_element(int*from, int total, int index) {
if(index != (total-1))
from[index] = from[total-1];
return total; // **DO NOT DECREASE** the total here
}
It is done by swapping the element with the last value.

C: insert element in empty heap

i'm supposed to write a code, that inserts numbers from stdin into an at first empty max-heap. my code just doesn't get the order of elements right, i found out, that it doesnt even enter the while loop before the third number. Anybody willing to help? Thanks in advance!
int heap_insert(heap* h, int key) {
if (h->size==MAX_HEAP_SIZE){
return(-1);
}
h->size=h->size+1;
int i=h->size-1;
h->array[i]=key;
int parent=(i-1)/2;
while (i>1 && h->array[parent]< key) {
h->array[i]= h->array[parent];
i = parent;
h->array[i]=key;
}
return(0);
}
it doesnt even enter the while loop before the third number
That part can be answered. Your loop won't go until i is 2 or greater...
while (i > 1 && h->array[parent]< key) {
^^^^^
Here's the code that sets i.
h->size = h->size+1;
int i = h->size-1;
That code is easier to understand like so:
int i = h->size;
h->size++;
First time through, i will be 0 (assuming h->size is initialized to 0, you didn't show your heap init code). Second time it will be 1. Third time it will be 2 and then finally the loop can run.
I'm guessing you want i >= 1 in the while loop so it will go on the second call.
As for why it's not working, the primary problem is you're forgetting to change parent in the loop.
/* i and parent initialized */
int i=h->size-1;
...
int parent=(i-1)/2;
while (i>1 && h->array[parent]< key) {
h->array[i]= h->array[parent];
/* i is changed, but where's parent? */
i = parent;
h->array[i]=key;
}
Here's what it should look like. I've changed i, which should only be used in loop indexes, to the more descriptive new.
/* new and parent initialized */
int new = h->size;
...
int parent = (new-1)/2;
while( new != 0 && h->array[parent] < key ) {
h->array[new] = h->array[parent];
h->array[parent] = key;
/* new AND parent changed */
new = parent;
parent = (new-1)/2;
}
Here's the complete code, plus I made the heap size dynamic because fixed size structures are a crutch best avoided.
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int size;
int max_size;
int *array;
} heap;
#define INIT_HEAP_SIZE 4
static heap *heap_init() {
heap *h = calloc(1, sizeof(heap));
h->max_size = INIT_HEAP_SIZE;
h->array = calloc(h->max_size, sizeof(int));
return h;
}
static void heap_destroy(heap *h) {
free(h->array);
free(h);
}
static void heap_grow(heap *h) {
h->max_size *= 2;
h->array = realloc( h->array, h->max_size * sizeof(int) );
}
static void heap_insert(heap* h, int key) {
if (h->size >= h->max_size) {
heap_grow(h);
}
int new = h->size;
h->size++;
h->array[new] = key;
int parent = (new-1)/2;
while( new != 0 && h->array[parent] < key ) {
h->array[new] = h->array[parent];
h->array[parent] = key;
new = parent;
parent = (new-1)/2;
}
return;
}
int main(void) {
heap *h = heap_init();
heap_insert(h, 23);
heap_insert(h, 11);
heap_insert(h, 42);
heap_insert(h, 5);
heap_insert(h, 99);
for( int i = 0; i < h->size; i++ ) {
printf("%d: %d\n", i, h->array[i]);
}
heap_destroy(h);
}
It doesn't enter the while loop before the 3rd number because your i is not greater than 1 until the 3rd number is entered. At 1st number i = 0, then 1 then 2.
For the loop, here's my advice on figuring out the problem: Suppose you enter the values 3, 5, 7. As soon as 5 is entered, you need a swap. 5 should become the new root, and 3 should be a child. (So maxheap property is kept) Then, when 7 is entered, another swap is in order. This time with 5. 7 becomes root, 3 and 5 are children. What does this tell you about the indexes? What happens if we insert 10, 16, 1 as well? More swaps? If you answer these properly the while loop should be easy to solve. (Hint: You need to keep swapping by starting from the child, and move to next parent until everything is in order)

Resources