Finding predecessor on a heap structure - c

This is the code i'm working and I have a function prototype to build :
node* pred ( int n,node * root) to find the predecessor
I have succeed with building the heap but here I am stuck.Please any held :D
#include<stdio.h>
#include<stdlib.h>
struct MaxHeap
{
int size;
int* array;
};
PrintArray(int* arr, int size);
struct MaxHeap* BuildMaxHeap(int* array, int size);
void HeapSort(int* array, int size);
void swap(int*a, int*b);
void MaxHeapify(struct MaxHeap* maxheap,int index);
int main()
{
int arr[] = {12, 11, 13, 5, 6, 7};
int size = (sizeof(arr))/(sizeof(arr[0]));
printf("\nGiven array of elements is :\n");
PrintArray(arr, size);
HeapSort(arr, size);
printf("\nThe sorted Array is :\n");
PrintArray(arr, size);
return 0;
}
PrintArray(int* arr, int size)
{
int i ;
for (i=0; i<size; i++)
printf("%5d", arr[i]);
printf("\n");
}
void swap(int*a, int*b)
{
int t = *a;
*a = *b;
*b = t;
}
void MaxHeapify(struct MaxHeap* maxheap,int index)
{
int largest = index;
int left = (index <<1) + 1;
int right = (index+1) << 1;
if(left < maxheap->size && maxheap->array[left] > maxheap->array[largest])
largest = left;
if(right < maxheap->size && maxheap->array[right] > maxheap->array[largest])
largest = right;
if(largest != index)
{
swap(&maxheap->array[index], &maxheap->array[largest]);
MaxHeapify(maxheap, largest);
}
}
struct MaxHeap* BuildMaxHeap(int* array, int size)
{
int i;
struct MaxHeap* maxheap = (struct MaxHeap*)malloc(sizeof(struct MaxHeap));
maxheap->size = size;
maxheap->array = array;
for(i= (maxheap->size - 2)/2; i>=0; i--)
MaxHeapify(maxheap, i);
return maxheap;
}
void HeapSort(int* array, int size)
{
struct MaxHeap* maxheap = BuildMaxHeap(array, size);
while(maxheap->size >1)
{
swap(&maxheap->array[0], &maxheap->array[maxheap->size-1]);
maxheap->size -= 1;
MaxHeapify(maxheap, 0);
}
}

Related

Remove negative numbers and sort an array

Good day everyone,
my task is to remove all negative numbers from an array, and shorten it (return the new length as the amount of positive numbers). I tried doing that by BubbleSort all negative number to the right, and new length would be (old length - number of swap). My code simply freezes up the system.
I would be grateful if you guys could help.
void swap(int *p, int *q) {
int h = *p;
*p = *q;
*q = h;
}
int remove_negatives(int *array, int length) {
int *a;
int n = length;
a = &array[n - 1];
for (int i = 0; i <= n - 1; i++) {
while (array < a) {
if (*array < 0) {
swap(a, array);
a--;
array++;
length--;
}
}
}
printialn(array, n);
return length;
};
int main(void) {
int a[] = {-1, 2, 4, -8, 3, 7, -8, 9, 3};
int l = sizeof(a) / sizeof(a[0]);
printiln(remove_negatives(a, l));
return 0;
}
The while loop never stops, that's probably the reason your code freezes.
Your code only changes the address when the if statement is true. Which the array in your main() will stuck on the second (a[1]) element. So if we change change the address when the if statement is false...
#include<stdio.h>
#include<stdlib.h>
void swap(int *p, int *q) {
int h = *p;
*p = *q;
*q = h;
}
int remove_negatives(int *array, int length) {
int *a, *head;
int n = length;
head = array;
a = &array[n - 1];
for (int i = 0; i <= n - 1; i++) {
while (array < a) {
if (*array >= 0) {
array++;
continue;
}
swap(a, array);
a--;
array++;
length--;
}
}
for (int i=0; i<length; i++) {
printf("%d ", *head);
head++;
}
puts("");
return length;
}
int main(void) {
int a[] = {-1, 2, 4, -8, 3, 7, -8, 9, 3};
int l = sizeof(a) / sizeof(a[0]);
remove_negatives(a, l);
return 0;
}
Now the while loop works, buts as #wovano said, the answer is still wrong. Your code isn't exactly a "bubble sort". you swap all the negative number to the end of the array and didn't actually sort the array.
So, let's start from the beginning.
To simplify the process, let bubble sort first, and then find the new array length.
#include<stdio.h>
#include<stdlib.h>
void swap(int *p, int *q) {
int h = *p;
*p = *q;
*q = h;
}
int bubble_sort(int *array, int length) {
int i, j;
// Bubble sort
for (i=0; i<length-1; i++) {
for (j=i+1; j<length; j++) {
if (array[i]<array[j]) swap(&array[i], &array[j]);
}
}
// Find new array length
for (i=length-1; i>=0; i--) {
if (array[i]>=0) break;
length--;
}
return length;
}
int main(void) {
int a[] = {-1, 2, 4, -8, 3, 7, -8, 9, 3};
int l = sizeof(a) / sizeof(a[0]);
l = bubble_sort(a, l);
for (int i=0; i<l; i++) printf("%d ", a[i]);
puts("");
return 0;
}

Passing pointer to an array as a parameter to a function

I tried to build a heap and finally print the elements in the form of an array.
Here it is the code (I know this doesn't really make sense but I just wanted to test my knowlwdge of heap and dynamic arrays):
#include <stdio.h>
#include <stdlib.h>
void heapiify(int *arr,int n, int i)
{
int largest=i;
int l=2*i+1; // left node
int r= 2*i+2; // right node
if(l<=n && *arr[l]>=*arr[i])
largest=l;
if (r <=n && *arr[r]<=*arr[i])
largest= r;
if(largest !=i)
{
int temp=*arr[i];
*arr[i]=*arr[largest];
*arr[largest]=temp;
}
heapify(*arr,n,largest);
}
void buildh(int *arr,int n,int r,int c)
{
int i;
for(i=n/2-1;i>=0;i--)
heapify(*arr,n,i);
output(*arr,r,c);
}
void output(int *arr,int r,int c)
{
int i,j;
for(i=0;i<r;i++)
{
for(j=0;j<c;j++)
{
printf("%d",*arr[i*c+j]);
}
printf("\n");
}
}
int main()
{
int i,j,r,c;
printf("enter the number of rows");
scanf("%d",&r);
printf("enter the number of columns");
scanf("%d",&c);
int n=r*c;
int *arr=malloc(n*sizeof(int));
for(i=0;i<r;i++)
{
for(j=0;j<c;j++)
scanf("%d",&arr[i*c+j]);
}
buildh(*arr,n,r,c);
}
I'm getting 9 errors which are all the same
invalid argument type of unary '*'( have int)
Your arr variable is of type pointer to int:
int *arr=malloc(n*sizeof(int));
So when you call buildh, which takes the same type, you have to pass it as-is:
buildh(arr,n,r,c);
Same for the other cases.
The problem is the dereference of arr, across your funtions in multiple places, and the passing of dereferenced *arr in your functions to int * parameters, you should pass arr, try:
//...
void heapify(int *arr, int n, int i)
{
int largest = i;
int l = 2 * i + 1; // left node
int r = 2 * i + 2; // right node
if (l <= n && arr[l] >= arr[i]) //here
largest = l;
if (r <= n && arr[r] <= arr[i]) //here
largest = r;
if (largest != i)
{
int temp = arr[i]; //here
arr[i] = arr[largest]; //here
arr[largest] = temp; //here
}
heapify(arr, n, largest); //here
}
void buildh(int *arr, int n, int r, int c)
{
int i;
for (i = n / 2 - 1; i >= 0; i--)
heapify(arr, n, i); //here
output(arr, r, c); //here
}
void output(int *arr, int r, int c)
{
int i, j;
for (i = 0; i < r; i++)
{
for (j = 0; j < c; j++)
{
printf("%d", arr[i * c + j]); //here
}
printf("\n");
}
}
int main()
{
//...
buildh(arr, n, r, c); //here
}

maximum subarray with static struct return types

I made maximum subarray algorithm, which something seems to be wrong with. Since C cannot return multiple values, function "maxarr" OR "maxcarr" is supposed to return three value-(start index, end index, and sum of it) in a static struct "rettype". However, those return value seems to be the same one(I have checked its memory adress, which was all same). I suppose that error occurs because static type variables are only declared once and do not be initialized more than one time, but I do not know how I can correct it.
#include <stdio.h>
#include <stdlib.h>
struct rettype
{
int a;
int b;
int c;
};
struct rettype* maxarr(int i, int j, int* array);
struct rettype* maxcarr(int i, int j, int* array);
int main(void)
{
int array[20];
int temp = 0;
int num = 0;
int len = 0;
struct rettype* ret;
printf("Type length in.\n");
scanf("%d", &len);
while (num<len)
{
printf("%dth element: ", num);
scanf("%d", &array[num]);
num++;
}
ret = maxarr(1, len, array);
printf("Maximum Subarray:\nfrom element %d to element %d with sum of %d\n", ret->a, ret->b, ret->c);
return 0;
}
struct rettype* maxarr(int i, int j, int* array)
{
static struct rettype retb;
static struct rettype ret;
struct rettype* fretr;
struct rettype* fretc;
struct rettype* fretl;
int hi=j;
int mid;
int low=i;
mid = ((hi + low) / 2);
if (i == j) {//base case
retb.a = i;
retb.b = j;
retb.c = *(array + i);
return &retb;
}
fretl = maxarr(i, mid, array);
fretr = maxarr(mid+1, j, array);
fretc = maxcarr(i, j, array);
if (fretl->c>fretr->c && fretl->c>fretc->c)
{
ret.a = fretl->a;
ret.b = fretl->b;
ret.c = fretl->c;
return &ret;
}
else if (fretr->c>fretl->c && fretr->c>fretc->c)
{
ret.a = fretr->a;
ret.b = fretr->b;
ret.c = fretr->c;
return &ret;
}
else
{
ret.a = fretc->a;
ret.b = fretc->b;
ret.c = fretc->c;
return &ret;
}
}
struct rettype* maxcarr(int i, int j, int* array)
{
int mid = (i + j) / 2;
static struct rettype ret;
int a = mid;
int b = mid+1;
int risum = -9999;
int lesum = -9999;
int sum = 0;
while (a-->i)
{
sum += *(array + a);
if (sum>lesum)
{
lesum = sum;
}
}
sum = 0;
while (b++<j)
{
sum += *(array + b);
if (sum>risum)
{
risum = sum;
}
}
sum = 0;
ret.a = a;
ret.b = b;
ret.c = risum + lesum;
return &ret;
}
you're using a static variable you're taking the address from to return to the caller.
In that case, you're sharing a same memory area for your return value, instead of creating separate ones.
Why not returning the value of the structure instead (C cannot return arrays, but can return structs, fortunately):
struct rettype maxcarr(int i, int j, int* array)
{
int mid = (i + j) / 2;
struct rettype ret;
...
return ret;
}
(and drop static for an auto variable which is copied when returned)
Note that you'll have to apply this pattern to all your routines.
Maximum subarray problem
Kadane's algorithm
#include <stdio.h>
struct rettype {
int start;
int end;
int sum;
};
struct rettype max_subarray(int array[], int length);
int main(void){
int array[20];
int len = 0, num;
struct rettype ret;
printf("Type length in.\n");
if(scanf("%d", &len) != 1){
printf("invalid input.\n");
return 1;
}
if(len > 20){
printf("too long.\n");
return 2;
}
for(num = 0; num < len; num++){
printf("%dth element: ", num);
if(scanf("%d", &array[num]) != 1){
printf("invalid input.\n");
len = num;
break;
}
}
if(len > 0){
ret = max_subarray(array, len);
printf("Maximum Subarray:\nfrom element %d to element %d with sum of %d\n", ret.start, ret.end, ret.sum);
}
return 0;
}
struct rettype max_subarray(int array[], int length){
struct rettype ret = { .sum = array[0] };
struct rettype curr = { .sum = array[0] };
for(int i = 1; i < length; ++i){
if(array[i] < array[i] + curr.sum){
curr.sum += array[i];
curr.end = i;
} else {
curr.sum = array[i];
curr.start = curr.end = i;
}
if(ret.sum < curr.sum){
ret = curr;
}
}
return ret;
}

[C]Reverse array with only pointers

I tried to reverse an array using only pointers. The program runs without any errors but it doesn't reverse the array. What's wrong with my code?
#include <stdio.h>
#define SIZE 10
void arrayReverseOutput(int * arr);
void arrayInput(int * arr);
void printArray(int * arr);
int main(void)
{
int arr[SIZE] = { 0 };
arrayInput(arr);
arrayReverseOutput(arr);
printArray(arr);
system("PAUSE");
return 0;
}
void arrayInput(int * arr){
int i = 0;
for (i = 0; i < SIZE; i++){
scanf("%d",(arr+i));
}
}
void arrayReverseOutput(int * arr){
int i = 0;
int k = SIZE-1;
int temp = 0;
for (i = 0; i < SIZE; i++){
temp = *(arr+i);
*(arr+i) = *(arr + k);
*(arr + k) = temp;
k--;
}
}
void printArray(int * arr){
int i = 0;
for (i = 0; i < SIZE; i++){
printf("%d ", *(arr+i));
}
}
The problem is, you are actually reversing the array twice, negating any changes achieved by swapping places.
Loop over only half of the array while swapping the elements, like
for (i = 0; i < SIZE/2; i++)
You can use 2 pointers to do so
void arrayReverseOutput(int *head, int *tail)
{
int temp = 0;
do
{
temp = *tail;
*tail = *head;
*head = temp;
}
while (head++ < tail--);
}
Complete code
#include <stdio.h>
#define SIZE 10
void arrayReverseOutput(int *head, int *tail);
void arrayInput(int * arr);
void printArray(int * arr);
int main(void)
{
int arr[SIZE] = { 0 };
arrayInput(arr);
arrayReverseOutput(arr, &arr[SIZE - 1]);
printArray(arr);
return 0;
}
void arrayInput(int * arr)
{
int i = 0;
for (i = 0; i < SIZE; i++)
{
scanf("%d", (arr + i));
}
}
void arrayReverseOutput(int *head, int *tail)
{
int temp = 0;
do
{
temp = *tail;
*tail = *head;
*head = temp;
}
while (head++ < tail--);
}
void printArray(int * arr)
{
int i = 0;
for (i = 0; i < SIZE; i++)
{
printf("%d ", *(arr + i));
}
}

Permutations recursive of repeated elements?

so i get two parameters, one is N [ how big the array would be] and nr_vals [ this is the range, if nr_vals == 2, then range would be ( 0~1)]. I'm getting an error in swap function EXC_BAD_ACCESS. and the permutations are not printing right. any ideas?
My Swap Function ;
void swap(int *a, int *b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
Main fun;
void perm_rec_1(int N, int nr_vals){
int array[N];
int tempAr = 0;
for (int arrayFiller = 0; arrayFiller <= N; arrayFiller++)
{
if (arrayFiller == nr_vals){
tempAr = 0;
}
array[arrayFiller] = tempAr;
tempAr++;
}
prem_rec_help(N, nr_vals, array);
}
Secondary;
void prem_rec_help(int N, int nr_vals, int array[])
{
int tempArray[N];
copy_array(array, tempArray, N);
show(tempArray, N);
int M = 0;
int solid = N;
last_helper(tempArray, array, M, N, solid, nr_vals);
}
Recursive Function;
void last_helper(int array[],int temp[], int M, int N, int soild, int nr_vals ){
if (M != N)
{
last_helper(array,temp, M+1, N, soild, nr_vals);
}
for ( int i = 0; i < nr_vals; i++)
{
temp[M] = i;
show(temp, soild);
}
M--;
if(M == 0)
{
for( int swaper = 0; swaper <= soild; swaper++)
{
swap(array[swaper], array[swaper+1]);
copy_array(array, temp, soild);
if(swaper == soild)
{
return;
}else{
last_helper(array,temp, M, N, soild, nr_vals);
}
}
}
}

Resources