0

I was solving a problem of kth smallest element using min-heap but got stuck as it's always giving me the first smallest element, so I guess my extractmin function is not working correctly.My approach was to make array into a min heap data structure in which root is the minimum element and then remove k-1 smallest elements and then simply return the value of root.

#include <iostream>

using namespace std;

void swap(int &x, int &y)
{
    int u = x;
    x = y;
    y = u;
}

int l(int p)
{
    return 2 * p + 1;
}

int r(int p)
{
    return 2 * p + 2;
}

void heapify(int arr[], int i, int n);

void makeheap(int arr[], int n)
{
    int last = n - 1;
    for (int i = (last - 1) / 2; i >= 0; i--)
    {
        heapify(arr, i, n);
    }
}

void heapify(int arr[], int i, int n)
{
int smallest = arr[i],y=0;
if (l(i) <= n - 1 && arr[l(i)] < arr[i])
{
    smallest = arr[l(i)];
}
if (r(i) <= n - 1 && arr[r(i)] < smallest)
{
    smallest = arr[r(i)];
 y=1;
}
if (smallest != arr[i])
{ 
    if(y==0){
    swap(arr[l(i)], arr[i]);}
    else if(y==1)
    {
        swap(arr[r(i)],arr[i]);
    }
    heapify(arr, i, n);
}
}

void extractmin(int arr[], int &n)
{
    swap(arr[0], arr[n - 1]);
    n--;
    heapify(arr, 0, n);
}

int getmin(int arr[])
{
    return arr[0];
}

int main()
{
    int T;
    cin >> T;
    while (T--)
    {
        int n;
        cin >> n;
        int arr[n];
        for (int i = 0; i < n; i++)
        {
            cin >> arr[i];
        }
        int k;
        cin >> k;
        makeheap(arr, n);
        for (int i = 0; i < k - 1; i++) {
            extractmin(arr, n);
        }

        cout << getmin(arr) << "\n";
    }
}

Input:

2
6
7 10 4 3 20 15
3
5

7 10 4 20 15
4

Expected Output:

7
15

My Output:

3
4
Hanoi
  • 3
  • 4
  • Sounds complicated. Why not just sort and return the kth element? Btw. *`int n; cin >> n; int arr[n];`* is not valid standard C++. – Swordfish Jan 17 '19 at 14:09
  • 1
    The solution to Goswin's answer is to make `smallest` an index into the array (i.e `smallest = l(i)` and `smallest = r(i)`) and then do `swap(arr[smallest], arr[i])`. – David G Jan 17 '19 at 15:05
  • Your debugger is an invaluable tool. Use it. If you don't know how, learn. Now. It'll save you a huge amount of time. You can thank me later. – Jim Mischel Jan 17 '19 at 16:12

1 Answers1

0

In heapify() you use

swap(smallest,arr[i]);

That exchanges the values in smallest and arr[i]. But arr[l(i)] or arr[r(i)] is not changed. What this actually does is copy the smaller value of arr[l(i)] and arr[r(i)] into arr[i].

Also in main you do

for (int i = 0; i < k - 1; i--) {

which counts i down till it hits INT_MIN instead of counting up to k. This quickly causes the heap to be empty and the code to segfault.

PS: Why not use the std::make_heap and friends?

Goswin von Brederlow
  • 11,875
  • 2
  • 24
  • 42
  • Still it fails on input:n=5; Array=12 5 787 1 23; k=2 Its Correct output is: 5 And Your Code's output is: 12 – Hanoi Jan 17 '19 at 15:26