fix heap properity data structure in C - c

I'm trying to write a function that restores the heap property . But all the time I come out bad results .
void fixHeap(int heapSize, struct Edge* edgeArray, int i){//edgeArray is our heap-array.
int leftSon = leftSonIndex(i);
int rightSon = rightSonIndex(i);
int change;
if((leftSon <= heapSize) && (edgeArray[i].cost < edgeArray[leftSon].cost)){
change = leftSon;
}else{
change = i;
if((rightSon <= heapSize) && (edgeArray[change].cost < edgeArray[rightSon].cost)){
change = rightSon;
}
}
if(change != i){
swap(edgeArray, i, change);
i = change;
fixHeap(heapSize, edgeArray, i);
}
}

The problem is that if you choose the leftSon as the change in the first if block, then you don't compare it with rightSon to check if rightSon > leftSon.
Hence your example would fail in cases like this -:
5
/ \
6 7
This is how it should be -:
void fixHeap( int heapSize, struct Edge* edgeArray, int i ) //edgeArray is our heap-array.
{
int leftSon = leftSonIndex( i );
int rightSon = rightSonIndex( i );
int change = i;
if ( ( leftSon <= heapSize ) && ( edgeArray[change].cost < edgeArray[leftSon].cost ) )
{
change = leftSon;
}
if ( ( rightSon <= heapSize ) && ( edgeArray[change].cost < edgeArray[rightSon].cost ) )
{
change = rightSon;
}
if ( change != i )
{
swap( edgeArray, i, change );
fixHeap( heapSize, edgeArray, change );
}
}

Related

Common elements within 2 arrays

I'm trying to write a function that copies all of the values in source1 which are also found in source2 into a destination and then returns the number of elements copied into the destination.
int common_elements(int length, int source1[length], int source2[length], int destination[length])
{
int counter = 0;
int i = 0;
while (i < length) {
int j = 0;
while (j < length) {
if ( source1[i] == source2[j]) {
destination[counter] = source1[i];
counter++;
}
j++;
}
i++;
}
return counter;
}
The problem is e.g. given (common_elements(5, {1,2,3,4,5}, {1,2,3,2,1}, [])), the correct input should be
1,2,3
return value: 3
However, the program is accounting for the duplicates and produces :
1,1,2,2,3
return value: 5
which is incorrect.
How can I remedy this?
In this while loop
int j = 0;
while (j < length) {
if ( source1[i] == source2[j]) {
destination[counter] = source1[i];
counter++;
}
j++;
}
you are counting all elements in the array source2 that are equal to the element source1[i].
I can suggest the following solution provided that the source arrays may not be changed within the function.
#include <stdio.h>
size_t common_elements( int destination[],
const int source1[],
const int source2[],
size_t n )
{
size_t counter = 0;
for ( size_t i = 0; i < n; i++ )
{
size_t number = 1;
for ( size_t j = 0; j < i; j++ )
{
if ( source1[i] == source1[j] ) ++number;
}
for ( size_t j = 0; number && j < n; j++ )
{
if ( source1[i] == source2[j] ) --number;
}
if ( number == 0 ) destination[counter++] = source1[i];
}
return counter;
}
int main(void)
{
enum { N = 5 };
int source1[N] = { 1, 2, 3, 4, 5 };
int source2[N] = { 1, 2, 3, 2, 1 };
int destination[N];
size_t n = common_elements( destination, source1, source2, N );
for ( size_t i = 0; i < n; i++ )
{
printf( "%d ", destination[i] );
}
putchar( '\n' );
return 0;
}
The program output is
1 2 3

removing duplicated names for array in c

this is what i have to make: c. It should be possible to remove an animal with a specified name. If more animals with the same name exist, it should remove all the animal with the same name.
this is my code:
void deleteAnimalByName(char *animalName, int *nrOfAnimals, ANIMAL *animalArray)
{
for(int i = 0; i < *nrOfAnimals; i ++)
{
if(strcmp((animalArray + i)->Name, animalName) == 0)
{
for(int j = i; j < *nrOfAnimals - 1; j++)
{
animalArray[j] = animalArray[j + 1];
}
(*nrOfAnimals)--;
}
}
}
the outcome after tyring to delete the animals with the same name:
Animals in shelter: 1
Name: ted
Species: Parrot
Age: 1
only one gets deleted, the other one stays. what could cause this?
For starters the function should be declared at least like
size_t deleteAnimalByName( ANIMAL *animalArray, size_t nrOfAnimals, const char *animalName );
And the function can be defined like
size_t deleteAnimalByName( ANIMAL *animalArray, size_t nrOfAnimals, const char *animalName )
{
size_t n = 0;
for ( size_t i = 0; i < nrOfAnimals; i++ )
{
if ( strcmp( animalArray[i].Name, animalName ) != 0 )
{
if ( n != i ) animalArray[n] = animalArray[i];
++n;
}
}
return n;
}
As for your approach then it at least is inefficient because you move all elements of the array one position left after finding an element that need to be deleted.
Here is a demonstrative program
#include <stdio.h>
#include <string.h>
typedef struct ANIMAL
{
char *Name;
} ANIMAL;
size_t deleteAnimalByName( ANIMAL *animalArray, size_t nrOfAnimals, const char *animalName )
{
size_t n = 0;
for ( size_t i = 0; i < nrOfAnimals; i++ )
{
if ( strcmp( animalArray[i].Name, animalName ) != 0 )
{
if ( n != i ) animalArray[n] = animalArray[i];
++n;
}
}
return n;
}
int main(void)
{
ANIMAL animalArray[] =
{
{ "hare" }, { "hare" }, { "fox" }, { "hare" }
};
size_t nrOfAnimals = sizeof( animalArray ) / sizeof( *animalArray );
nrOfAnimals = deleteAnimalByName( animalArray, nrOfAnimals, "hare" );
for ( size_t i = 0; i < nrOfAnimals; i++ )
{
printf( "%s ", animalArray[i].Name );
}
putchar( '\n' );
return 0;
}
The program output is
fox

All max elements and their postition of array

So, for example, I have array: [1, 4, 9, 3, 9]
I need to find all max elements [9, 9] and their index [2, 4]
How can I do this? In C language
int i, pom, max;
max=*gradovi;
for(i=0;i<n;i++) {
if(*(gradovi+i)>max) {
max=*(gradovi+i);
pom=i;
}
if(*(gradovi+i)==max) {
pom=i;
}
}
return pom;
I need postions of all max elemenents, but this print just last
In any case you need a container that will store the indices of the elements with the maximum value.
You can allocate memory dynamically for such a container.
Here is a demonstrative program.
#include <stdio.h>
#include <stdlib.h>
size_t max_elements( const int a[], size_t n, size_t **result )
{
*result = NULL;
size_t count = 0;
if ( n != 0 )
{
size_t max_i = 0;
count = 1;
for ( size_t i = 1; i < n; i++ )
{
if ( a[max_i] < a[i] )
{
max_i = i;
count = 1;
}
else if ( !( a[i] < a[max_i] ) )
{
++count;
}
}
*result = malloc( count * sizeof( size_t ) );
if ( *result != NULL )
{
for ( size_t i = max_i, j = 0; i < n && j < count; i++ )
{
if ( !( a[i] < a[max_i ] ) ) ( *result )[j++] = i;
}
}
}
return count;
}
int main(void)
{
int a[] = { 1, 4, 9, 3, 9 };
const size_t N = sizeof( a ) / sizeof( *a );
size_t *result = NULL;
size_t count = max_elements( a, N, &result );
for ( size_t i = 0; i < count; i++ )
{
printf( "%zu: %d, ", result[i], a[result[i]] );
}
putchar( '\n' );
free( result );
return 0;
}
Its output is
2: 9, 4: 9,
If the returned value from the function is not equal to 0 but the pointer result was set to NULL then it means that there was a memory allocation error. You can check such a situation.
I'm stupid, it's simple solution:
void maks(int *gradovi, int n){
int i, pom, max;
max=*gradovi;
for(i=1;i<n;i++){
if(*(gradovi+i)>max){
max=*(gradovi+i);
}
if(*(gradovi+i)==max){
pom=i;
printf("Najvise zarazenih je u gradu sa indeksom: %d\n", pom);
}
}
}

Wrong output in binary search

I am using binary search algorithm to find a number in a predefined array, but if i am entering the value already in an array i am getting correct answer, but on entering a value not in an array like 101,100,121 i am just getting number 10 as output
#include <stdio.h>
int binarysearch(int A[],int key);
int main()
{
int key,answer;
int A[10]={0,5,8,10,12,14,15,18,19,21};
scanf("%d",&key);
answer=binarysearch(A,key);
if (answer!=-1)
{
printf("%d",answer);
}
else
{
puts("NOT FOUND");
}
}
int binarysearch(int A[],int key)
{
int i;
int h,l,m;
h=10;
l=0;
while(l<=h)
{
m=(h+l)/2;
if(A[m]==key)
{
return m;
}
else if(key<A[m])
{
h=m-1;
}
else
{
l=m+1;
}
}
return -1;
}
Change the condition
while(l<=h)
to
while ( l < h )
And change this code snippet
else if(key<A[m])
{
h=m-1;
}
the following way
else if(key<A[m])
{
h = m;
}
The function could be defined like
int binarysearch( const int A[], int n, int key )
{
int l = 0;
int h = n;
while ( l < h )
{
int m = ( h + l ) / 2;
if ( A[m] == key )
{
return m;
}
else if( key < A[m] )
{
h = m;
}
else
{
l = m + 1;
}
}
return -1;
}
And called like
answer=binarysearch( A, 10, key );

Is the following procedure the correct way to delete 2 linked lists that have some common elements?

struct node* tempA;
struct node* tempB;
n = 501;
m = 501;
tempA = A;
tempB = B;
while ( tempA != NULL && tempB != NULL )
{
if ( tempA->data == tempB->data )
{
int common = tempA->data;
if (fastintersect(common+n,block,closed_area)||fastintersect(common-n,block,closed_area)||(fastintersect(common-1,block,closed_area) && common%n != 1)||(fastintersect(common+1,block,closed_area) && common%n != 0 ))
{
AppendNode(&C,common);
tempA = tempA->next;
tempB = tempB->next;
if( search(A,common) != length(A) )
{
DeleteNode(&A,common);
}
else
{
DeleteEndNode(A);
}
if( search(B,common) != length(B) )
{
DeleteNode(&B,common);
}
else
{
DeleteEndNode(B);
}
}
else
{
tempA = tempA->next ;
tempB = tempB->next ;
}
}
else if ( tempA->data > tempB->data )
tempB = tempB->next;
else
tempA = tempA->next;
}
// The fastintersect function
int fastintersect(int x,int arr[],int sizearr)
{
int found = 0;
int lower = 0;
int upper = sizearr - 1 ;int i=0;
if( (x == arr[lower]) || (x == arr[upper]) )
{
found = 1;
}
else if ( x > arr[lower] && x < arr[upper])
{
while ( lower <= upper )
{
int middle = ( lower + upper ) / 2;
if ( x > arr[middle])
{ lower = middle +1 ;}
else if (x < arr[middle])
{upper = middle - 1;}
else
{ found = 1;break;}
}
}
return found;
}
This is a function to delete the common elements of 2 sorted linked lists A and B . When there are common elements the fastintersect criterion is checked and corresponding elements are deleted and new linked list C is generated whose elements are the ones which satisfy the common elements criteria as well as the fastintersect check .Block is just a matrix which has some values against which the common is checked and if present will return a value 1 else 0. Am I doing the deleting correctly ? Is this a valid code ?

Resources