Max heapify infinite loop when used on array but not vector - c++

I am trying to convert a max-heapify function that I used for a vector to work with sorting an array of ints, however, when I run it, I am running into an infinite loop.
I believe the logic of my algorithm seems to be right, however, my siftdown function doesnt seem to function properly.
void Sort::heapify(int *array, int size){
for(int i = (size-2)/2;i >= 0;i--){
siftdown(array, i, size);
}
}
void Sort::siftdown(int *array, int i, int size){
if(i >= size || i < 0){
cout << "i is >= size of playerArray or i < 0. i: " << i << endl;
return;
}
cout<< "passed something" <<endl;
while(!isLeaf(array, i, size)){
cout<<"!isLeaf"<<endl;
int max = getLeft(i);
if(max + 1 < size && array[max] < array[max +1]){
max++;
cout << "added to max.";
}
if (array[i] > array[max]){
cout<< "array[i] is > than array[max]"<<endl;
return;
}
swap(i, max);
i = max;
}
cout<<"isLeaf"<<endl;
}
int Sort::getLeft(int index){
//gets the left most leaf
int left = 2*index+1;
return left;
}
bool Sort::isLeaf(int *array, int index, int size){
//A node is a leaf node if both left and right child nodes of it are NULL.
int left = 2*index+1;
int right = left+1;
if(left>size && right>size) return true;
return false;
}
Any help would be greatly appreciated. Thanks!

When you write (in the body of while in Sort::siftdown())
swap(i, max);
i = max;
you're ending with i and max with the old value of i; so you repeat
while(!isLeaf(array, i, size))
with the same values.
Loop!

Related

How does this recursive function "end" rather than loop indefinitely (or throw an error)?

I came across this subset_sum coding problem/solution and am trying to understand in depth how it works.
To quickly summarize the problem: given an array of length n, find the largest number in the array and then find if there is any combination of numbers inside that array that, when summed, equal the largest number.
The setup of this problem is simple enough, but the actual function of the recursive function that checks all of the array combinations is where I'm a little confused. I've been reading about recursive functions and understand it conceptually, however, I'm having difficult following the exact flow of this particular program and am hoping someone could provide some assistance here.
string flag = "false";
void checkSubsets(int *arr, int i, int length, int *subset, int j, int max) {
if (i == length) {
int index = 0;
int setSum = 0;
while (index<j) {
setSum = setSum + subset[index];
++index;
if (setSum == max) {
flag = "true";
}
}
return;
}
checkSubsets(arr,i+1,length,subset,j, max);
subset[j] = arr[i];
checkSubsets(arr,i+1,length,subset,j+1, max);
}
string ArrayAddition(int arr[], int arrLength) {
int subset[100];
int max = arr[0];
int maxIndex = 0;
for (int i = 0; i<arrLength;i++) {
if (arr[i] > max) {
max = arr[i];
maxIndex = i;
}
}
for (int j = maxIndex; j<arrLength-1;j++) {
arr[j] = arr[j+1];
}
arr[arrLength-1] = 0;
checkSubsets(arr, 0, arrLength, subset, 0, max);
return flag;
}
The recursion ends when i reaches length:
void checkSubsets(int *arr, int i, int length, int *subset, int j, int max) {
if (i == length) {
// stuff
return; // ends here.
}
// else recurse:
checkSubsets(arr,i+1,length,subset,j, max); // i+1
subset[j] = arr[i];
checkSubsets(arr,i+1,length,subset,j+1, max); // i+1
}
For each call, you call it with i+1 and when i == length, it does not recurse deeper but does instead return.

how to use user input array in heap sorting

I'm a beginner so please excuse me if it is a dumb question.
I am trying to code a heap sort that takes input from user in an array and heap sorts it but i can not find a way to implement user input array in my code.
at the end, in the main function, i have to use array arr[]={} but i either have to define the elements or the number of elements so it creates zeros if i define the array as arr[10]={}
here is the code :
// Heap Sort in C++
#include <iostream>
using namespace std;
void heapify(int arr[], int n, int i) {
// Find largest among root, left child and right child
int largest = i;
int left = 2 * i + 1;
int right = 2 * i + 2;
if (left < n && arr[left] > arr[largest])
largest = left;
if (right < n && arr[right] > arr[largest])
largest = right;
// Swap and continue heapifying if root is not largest
if (largest != i) {
swap(arr[i], arr[largest]);
heapify(arr, n, largest);
}
}
// main function to do heap sort
void heapSort(int arr[], int n) {
// Build max heap
for (int i = n / 2 - 1; i >= 0; i--)
heapify(arr, n, i);
// Heap sort
for (int i = n - 1; i >= 0; i--) {
swap(arr[0], arr[i]);
// Heapify root element to get highest element at root again
heapify(arr, i, 0);
}
}
// Print an array
void printArray(int arr[], int n) {
for (int i = 0; i < n; ++i)
cout << arr[i] << " ";
cout << "\n";
}
// Driver code
int main() {
int arr[10] = { };
cout << "Enter the numbers : " << endl;
for (int x = 1; x <= 5; x++)
{
cin >> arr[x];
}
int n = sizeof(arr) / sizeof(arr[0]);
heapSort(arr, n);
cout << "Sorted array is \n";
printArray(arr, n);
}
here is the output :
code output image
You can consider std::vector and pass it by reference to your heapify(...) to save memory.

Not able to find error in my Heap Sort Code. Not executing properly. C++

Please help. I have reviewed it and seem to be missing the error. It seems to be exiting out of the function Max_Heapify and not running my second loop to print the sorted array. This was for an assignment I have already turned in but I am trying to learn the error of my ways to make sure I can do well on the test.
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
// declare global variable of heap size
int heap_size = 7;
// function to determine left child node of the tree
int Left(int i){
return 2*i+1;
}
// function to determine right child node of the tree
int Right(int i){
return 2*i + 2;
}
// create heap tree
void Max_Heapify (int array[], int index){
int left_child_index = Left(index);
int right_child_index = Right(index);
int largest;
// check if left child is smaller than heap size and if left child is bigger than parent
// if so, save variable as largest value, otherwise, largest value will stay as index
if ( (left_child_index < heap_size) && (array[left_child_index] > array[index]) )
largest = left_child_index;
else largest = index;
// check if right child is smaller than heap and if bigger than largest value
if ((right_child_index < heap_size) && (array[right_child_index] > array[largest]) )
largest = right_child_index;
// exchange largest values
if (largest != index)
swap(array[index], array[largest]);
Max_Heapify(array,largest);
}
// check leaves
void Build_Max_Heap(int array[]){
for (int i = (heap_size / 2 ) - 1; i >= 0; i--)
Max_Heapify (array, i);
}
void Heapsort(int array[]) {
Build_Max_Heap(array);
for (int i = heap_size-1; i >= 0; i--){
swap(array[0], array[i]);
Max_Heapify(array,0);
}
}
int main(){
int arr[7] = {21, 9, 50, 7, 6, 33, 77};
cout << "Non Heapified Array: " << endl;
for (int i = 0; i < heap_size; i++){
cout << arr[i] << endl;
}
Heapsort(arr);
for (int i = 0; i < heap_size; i++){
cout << arr[i]<< endl;
}
}
Your MaxHeapify never terminates. You should call MaxHeapify only if largest is not i. If largest is i, then nothing needs to be done here as the elements are already heapified.
if (largest != index){
swap(array[index], array[largest]);
Max_Heapify(array,largest);
}

Min heap does not work as intended in C++

I am having problem with the min heap algorithm.
The code I programmed returned an array that incorrectly arranged, below is my code, can someone help me to find where should I change?
Thank you.
The data was under ELEMENT arr[], where ELEMENT is a struct:
struct ELEMENT{
int key;
};
void constructMinHeap(ELEMENT arr[], int size, int num){
int left = leftNode(num);
int right = rightNode(num);
int min;
if (left < size && arr[left].key < arr[num].key){
min = left;
} else{
min = num;
}
if (right < size && arr[right].key < arr[min].key){
min = right;
}
if(min != num){
swap(&arr[num].key, &arr[min].key);
constructMinHeap(arr, size, num);
}
}
ELEMENT* buildHelper (ELEMENT arr[], int size){
int i = size / 2 - 1;
while (i >= 0){
constructMinHeap(arr, size, i);
i--;
}
return arr;
}
And here is the code for calculating leftNode and rightNode:
int leftNode(int num){
return 2 * num + 1;
}
int rightNode(int num){
return (2 * num) + 2;
}
The following code is for storing data into the ELEMENT arr[]:
ifstream infile("somefilename.txt");
if (infile.good()) {
int i = 0;
int size;
infile >> size;
ELEMENT arr[size];
while (i < size){
infile >> arr[i].key;
i++;
}
BuildHeap(h, arr, size);
infile.close();
} else{
cout << "File \"somefilename.txt\" does not exist in the current directory.";
}
When the file's content is
4 4 3 2 1
The feedback becomes:
1 4 2 3
Your recursive call for num is incorrect, it has no progress since it calls the same num again. In case if the node is swapped with its smallest child, that child should be further pushed down until it takes its proper place. This will guarantee that the binary subtree rooted at num is heapified
The correct recursion is the following (you didn't show the swap so I added my own one):
void swap(ELEMENT* e1, ELEMENT* e2)
{
int tmp = e1->key;
e1->key = e2->key;
e2->key = tmp;
}
void constructMinHeap(ELEMENT arr[], int size, int num){
int left = leftNode(num);
int right = rightNode(num);
int min = num;
if (left < size && arr[left].key < arr[min].key){
min = left;
}
if (right < size && arr[right].key < arr[min].key){
min = right;
}
if(min != num)
{
swap(&arr[num], &arr[min]);
constructMinHeap(arr, size, min);
}
}

Bubble sort the total number of comparisons and swaps

I have this code for bubble sort in c++. At first it generates random numbers and puts them inside an array. After that I call my bubbleSort function, which does the sorting. Everything works fine. However I was curious how can I find a number of total comparisons and number swapping that bubble sort makes?
I created a CountBubbleSort integer for comparisons. However I'm not sure in which part of my code should I increment it. I was thinking to add it after second for loop, inside first one. Hope you understand what I mean. Is it right or not? Number of comparisons defines this formula n*(n-1))/2. And with swaps it is 3*(n-1). But how can I implement it to my code? Thanks for the help guys.
void swap(double *xp, double *yp)
{
double temp = *xp;
*xp = *yp;
*yp = temp;
}
double *Data;
double* A;
double n, temp;
void generate(int _n, const char *_file);
void read(const char *_file);
void printArray(double arr[], int n);
void bubbleSort(double arr[], int n);
int main()
{
int m;
int CountBubbleSort = 0;
srand(time(NULL));
cout << "Amount of random numbers you want: ";
cin >> m;
cout << "Generating random data ..." << endl;
generate(m, "duom.txt");
cout << "Reading data" << endl;
read("duom.txt");
A = new double[n];
for (int i = 0; i < n; i++) {
A[i] = Data[i];
}
cout << "Randomly generated array" << endl;
printArray(A, n);
// Bubble Sort
bubbleSort(A, n);
cout << "Array after bubble sort" << endl;
printArray(A, n);
return 0;
}
void bubbleSort(double arr[], int n)
{
bool swapped;
for (int i = 0; i < n - 1; i++)
{
swapped = false;
for (int j = 0; j < n - i - 1; j++)
{
if (arr[j] > arr[j + 1])
{
swap(&arr[j], &arr[j + 1]);
swapped = true;
}
}
// Should I add CountBubbleSort += i here or not?
if (swapped == false)
break;
}
}
void printArray(double arr[], int n) {
for (int i = 0; i < n; i++) {
cout << A[i] << endl;
}
}
This is a relatively straightforward change:
Increment comparison count before the if statement
Increment the swap counter inside the if statement
Take two int& parameters for the count, like this:
void bubbleSortCounted(double arr[], int n, int& countComparisons, int& countSwaps);
The code incrementing the counters would look like this:
countComparisons++;
if (arr[j] > arr[j + 1])
{
countSwaps++;
swap(&arr[j], &arr[j + 1]);
swapped = true;
}
The call from the main() would look like this:
int cmp = 0, swp = 0;
bubbleSort(A, n, cmp, swp);
std::cout << cmp << " comparisons, " << swp << " swaps" << std::endl;
However I was curious how can I find a number of total comparisons and number swapping that bubble sort makes? I created a CountBubbleSort integer for comparisons. However I'm not sure in which part of my code should I increment it.
There's exactly one line in your bubbleSort() function where you actually compare two elements in the array, so it stands to reason that if you want to count the number of times you compare elements, you should increment the counter either immediately before or immediately after the comparison happens.