-1

Numbers from 1 to n are added to min-heap in a certain order. For each number find out how many times it changed its position in the min-heap.

Clarification: for addition use method Insert(), add nodes in the same order as they are in the input.

Input: In the first line is the number n. In the second line, divided by spaces, are n numbers from 1 to n.

Output: n numbers divided by spaces: i-th number indicates the number of position changes of the number i in the constructed min-heap.

i.e. 5 4 3 2 1

answer 2 3 3 2 2

public class MinHeap {
private int[] heap;
private int size;
private int maxsize;

public MinHeap(int maxsize) {
    this.maxsize = maxsize;
    this.size = 0;
    heap = new int[this.maxsize + 1];
    heap[0] = Integer.MIN_VALUE;
}

private void swap(int fpos, int spos) {
    int tmp;
    tmp = heap[fpos];
    heap[fpos] = heap[spos];
    heap[spos] = tmp;
}

private void minHeapify(int pos) {
    if (2 * pos == size) {
        if (heap[pos] > heap[2 * pos]) {
            swap(pos, 2 * pos);
            minHeapify(2 * pos);
        }
        return;
    }

    if (2 * pos <= size) {
        if (heap[pos] > heap[2 * pos] || heap[pos] > heap[2 * pos + 1]) {
            if (heap[2 * pos] < heap[2 * pos + 1]) {
                swap(pos, 2 * pos);
                minHeapify(2 * pos);
            }
            else {
                swap(pos, 2 * pos + 1);
                minHeapify(2 * pos + 1);
            }
        }
    }
}

public void insert(int element) {
    heap[++size] = element;
    int current = size;

    while (heap[current] < heap[current / 2]) {
        swap(current, current / 2);
        current = current / 2;
    }
}

public void minHeap() {
    for (int pos = (size / 2); pos >= 1; pos--) {
        minHeapify(pos);
    }
}

public int extractMin() {
    if (size == 0) {
        throw new NoSuchElementException("Heap is empty");
    }
    int popped = heap[1];
    heap[1] = heap[size--];
    minHeapify(1);
    return popped;
}

}

I don't understand how to count

JohnPaolo
  • 3
  • 2
  • Your heap implementation puts the root at index 1 in the array. Arrays start at 0, and if you're building a heap in a 0-based language like Java, your heap should start at 0. See https://stackoverflow.com/a/49806133/56778 – Jim Mischel May 25 '20 at 17:17

1 Answers1

0

Update after comment

I don't know how you got the output "0 1 2 2 3". I would have expected "0 1 1 2 2". But that's irrelevant now.

I see that I misunderstood your original question. You don't want the number of swaps as each item is inserted. You want to know how many times each item changes position throughout the life of the heap.

You'll need to build a map with the key being the item's value, and the value part being the number of times the item was involved in a swap operation. In your swap method, you check the map to see if the item exists. If the item doesn't exist in the map, add it with a count of 1. If it does exist, increment its count.

When you're done adding items to the heap, you can print the contents of the map.

Original answer

You could have a class variable called numSwaps:

private int numSwaps;

And then in your swap method, you increment it whenever there's a swap:

private void swap(int fpos, int spos) {
    int tmp;
    tmp = heap[fpos];
    heap[fpos] = heap[spos];
    heap[spos] = tmp;
    numSwaps = numSwaps + 1;
}

And provide methods clearSwaps (to reset to 0) and getSwaps (to return the current number of swaps).

Jim Mischel
  • 131,090
  • 20
  • 188
  • 351
  • Nope it doesn't help. I modified MinHeap class: re-create Heap with zero-based (add a first value from scanner.nextInt), then continue read other elements from scanner. When I add 5 4 3 2 1, console answer 0 1 2 2 3, but answer should be 2 3 3 2 2 – JohnPaolo May 25 '20 at 18:45
  • damn it, I tried the Map a few days ago and could not understand why the right answer did not come out and threw it, thinking that I was digging in the wrong direction, but it turned out that the Map really would help. Thank you – JohnPaolo May 26 '20 at 17:54