heapsort implementation in c++ - c++

i have following code for heapsort
#include <iostream>
using namespace std;
void exch(int a[],int i,int j){
int s=a[i];
a[i]=a[j];
a[j]=s;
}
void sink(int a[],int k,int n){
//int n=sizeof(a)/sizeof(int);
while(2*k<=n){
int j=2*k;
if (j<n && (a[j]<a[j+1])) j++;
if (a[k]>=a[j]) break;
exch(a,k,j);
k=j;
}
}
void heapsort(int a[]){
int n=sizeof(a)/sizeof(int);
for (int k=n/2;k>=1;k--)
sink(a,k,n);
while(n>1){
exch(a,1,n--);
sink(a,1,n);
}
}
int main(){
int a[]={12,3,5,1,67,10,9.20};
int n=sizeof(a)/sizeof(int);
heapsort(a);
for (int i=0;i<n;i++){
cout<<a[i]<<" ";
}
return 0;
}
but result it shows me looks like this
12 3 5 1 67 10 9 Press any key to continue . . .
also look that in my array total number is 8 and here it shows me 7 as output, i think core of this problem should be this
1>c:\users\datuashvili\documents\visual studio 2010\projects\heap\heap\heap.cpp(36): warning C4244: 'initializing' : conversion from 'double' to 'int', possible loss of data
it seams that possible loss of data while converting from double to int force code works incorrectly,am i correct or wrong?please help me

You wrote a . instead of a , between the 9 and 20:
int a[]={12,3,5,1,67,10,9.20};
This results in 7 numbers, the last of which is the double 9.20 which gets converted to an int.
Additionally, this code is wrong:
void heapsort(int a[]){
int n=sizeof(a)/sizeof(int);
Array arguments are actually passed as pointers, so sizeof(a) won't give you the correct result. You should pass in the array size as an additional parameter instead.

One problem I can see immediately is here:
void heapsort(int a[]){
int n=sizeof(a)/sizeof(int);
You cannot pass an entire array as a parameter to a function in C/C++. The parameter syntax int a[] is, of course, confusing, but in fact it's equivalent to int* a. heapsort() can't know the size of the array to which a points. You have to pass the size in as a separate parameter.

In addition to all the other comments (sizeof(a), passing [] as arguments, having a . in the init-list), you want to write C++-code, right? But it looks quite C'ish, except for the iostream. Thereore:
use std::vector<int> from #include <vector> (add elements with push_back for example)
pass it as as a reference, i.e. void heapsort(std::vector<int> &a)
consider using std::swap( a[i], a[j] ); instead of exch

Related

Shakersort c++, error: invalid conversion from ‘int’ to ‘int* - I can't find where I mixed integer and pointer to integers

#include <iostream>
using namespace std;
const int up=18;
int realArray[up]={12,28,75,16,66,6,121,19,195,56,108,221,19,93,104,127,73,22}; //definition of a random array
void shakersort(int formArray[up]);//shakersort declared
void tauschen(int *a,int *b){int zw= *a; *a=*b; *b=zw;}
int main()
{
shakersort(realArray[up]); //here happens the error of the conversion
return 0;
}
void shakersort(int formArray[up]){ //the code
for(int i=0; i<up/2;i++){
for (i=0; i<up-1;i++){
if(formArray[i]>formArray[i+1]){
tauschen(&formArray[i], &formArray[i+1]);
}
}
for (int k=up-1; k>0;i--){
if(formArray[k]>formArray[k-1]){
tauschen(&formArray[k], &formArray[k-1]);
}
}
}
}
Not sure why there is a conversion error. Used the same code at declaration and application so not sure why it's not working.
up is an int with value 18 so in this line
shakersort(realArray[up]);
you are basically writing
shakersort(realArray[18]);
which will index a single value from your array (which also happens to be out of bounds, which would therefore be undefined behavior). Instead just pass the array itself
shakersort(realArray);
though I would encourage you to look into using std::vector instead
void shakersort(std::vector<int>& formArray);
so you don't need a global variable floating around to determine the array size, you can just use formArray.size()

Pointer to an Integer Array and Printing Sum

So, I was told to...
"Write a function Adder() that receives a pointer to an integer array as input, and uses this
pointer to return the sum of elements of the array."
And I was pretty successful. My code is
#include <bits/stdc++.h>
using namespace std;
int Adder (int *ptr)
{
int sum=0;
for (int i=0; i<5; i++)
{
sum=*(ptr+i)+sum;
}
return sum;
}
int main(){
int array[5]={1,1,1,1,1};
int sum;
int *ptr=array;
Adder(ptr);
sum=Adder(ptr);
cout<<sum;
}
The thing I can't understand is where I
Adder(ptr)
and then
int Adder (int *ptr)
"ptr" holds the address, right? While, " *ptr " holds the actual value. I can't understand how this worked. Can someone please explain?
The reason why this works is because adding 1 to an int pointer (in your case ptr) will actually add the size of an int (which can vary depending on the machine).
See the answers to this question for a more detailed explanation: Why a pointer + 1 add 4 actually
The line
int Adder (int *ptr)
defines a function that takes a pointer to an int as its argument. In this context, *ptr does not refer to the value ptr is pointing to.
The line
Adder(ptr);
invokes that function, passing the local pointer named ptr.

Find number of elements in array passed to a function as argument.

I was trying to make a function for finding number of elements in an array. For this I approached for following code:
#include<iostream>
#include<stdlib>
int no_of_ele(A[]) //function to return size of array
{
return (sizeof(A)/sizeof(A[0]);
}
void main()
{
system("cls");
int arr[5] = {1,2,3,4,5};
cout<<"Number of elements in array are "<<no_of_ele(arr)<<endl;
system("pause");
}
In this approach I got output as follows:
Then, I did this:
cout<<"Size of array is "<<sizeof(arr)<<endl;
cout<<"Size of data type is "<<sizeof(arr[0]);
Now I got absolutely correct output of size as follows:
Why is it?
There are better ways these days, but the closest is:
#include<iostream>
template<std::size_t N>
int no_of_ele(int (&A)[N]){
return sizeof(A)/sizeof(A[0]); // or just return N
}
int main(int argc, char* argv[]){
int arr[5] = {1,2,3,4,5};
std::cout<<"Number of elements in array are "<<no_of_ele(arr)<<std::endl;
return 0;
}
Greetings to 1998. The question is, does Turbo C++ support templates?
See here for more: Is it possible to overload a function that can tell a fixed array from a pointer?
The array decayed to pointer when passed to your function.
sizeof(int)/sizeof(int)... = 1
Reason for this, the parameters are pushed on stack to the function. The compiler as declared by your function declaration will just send the address of your array.
When passing an array as a parameter
int func(int arr[])
Is just as:
int func(int *arr)
Giving an array as a function argument you can't determine its size using the sizeof.

Passing multidimensional arrays gives and error

I am trying to pass a multidimensional array to a function. When I try to compile I an getting an error saying
[Error] cannot convert 'int (*)[3]' to 'int (*)[2]' for argument '1' to 'void reve(int (*)[2], int)'
What is the problem ? What am I doing wrong? Following is the code I wrote.
#include <iostream>
using namespace std;
const int rows=2;
const int cols=2;
const int n = 3;
void reve(int arr[rows][cols],int n){
int br[3][3],i,j,k,l;
for(i=n-1,k=0;i>=0,k<n;i--,k++){
cout<<endl;
for(j=n-1,l=0;j>=0,l<n;j--,l++)
br[k][l]=arr[i][j];
}
for(i=0;i<n;i++){
for(j=0;j<n;j++)
arr[i][j]=br[i][j];
}
}
int main() {
int i,j,k,l,ar[3][3],br[3][3];
for(i=0;i<3;i++)
for(j=0;j<3;j++)
cin>>ar[i][j];
int n=3;
reve(ar,n);
for(i=0;i<3;i++){
cout<<endl;
for(j=0;j<3;j++)
cout<<ar[i][j];
}
return 0;
}
When you use a 2-d array in a function call, it decays into a pointer type. However, all dimensions but the first one must match exactly.
If the argument type of a function is int (*arg)[2], then, you can't use a variable that is declared as int var[3][3] to call the function. var decays to a pointer whose type is int (*)[3].
It is confusing at first because it seems to work in case of 1-d arrays.
void foo(int arg[10])
{
}
int var[2];
foo(var); // OK
That's because the compiler ignores the size of the first dimension of the array. The above definition of foo is same as:
void foo(int arg[])
{
}
and
void foo(int* arg)
{
}
However, for a multidimensional array, the size of all but the fist dimension must match exactly. Otherwise, they are different types.
The reve() function expects an array of [2][2] but you're passing a [3][3] array.
The ar array in main() is declared as int ar[3][3] while it should have been int ar[rows][cols]
You have reserved 2 blocks in memory. And in your loop, you are taking it from 2 to 0 that makes it 3. Do the following changes.
const int n= 2;
And it should work for your program.

cannot display the result of each one of my function

I wrote a code that computes the sum of components of an array which is randomly filled with values between 0 and 1. I have to write two functions, one is iterative, and the other one is recursive. Both should do the same work. The two functions I wrote work fine when I call only one at the time. However, if i try to call the two functions in the main, I can see the result of one only, but cannot see the result from the other one. In addition, my recursive function tends to get called one extra time. I have noticed that if I put getch() as comment in recursive_function(). I know I am missing something, but I cannot figure that out. Thanks for your help. here is the code. i am using Dev-C++.
#include <iostream>
#include<conio.h>
#include <stdlib.h>
using namespace std;
//headers of the thre functions
int random_value(int array[], int size);
int iterative_function (int array[], int size, int sum);
int recursive_function ( int size, int array[], int index, int sum);
int main()
{
int size;int array[size]; int sum=0;
int index=0;
cout<<"enter the size of the array"<<endl;
cin>>size; //enter the size ofthe array...
random_value(array, size);
iterative_function (array, size, sum);
recursive_function ( size, array, index, sum);
getch();
return 0;
}
int random_value(int array[], int size)
{ cout<<"here is the value returned by rand()"<<endl;
for(int i=0;i<size;i++)
{ array[i]=( rand() % (0-2));
cout<<array[i]<<endl;
}
}
int iterative_function (int array[], int size, int sum)
{
int i,j, number, value; i=0;
cout<<"from the iterative function"<<endl;
cout<<"------"<<endl;
for(i=0;i<size;i++)
sum=sum+array[i];
cout<<"sum of the array="<<sum<<endl;
getch();
return 0; //exit the function. Program terminated succesfully.
}
int recursive_function ( int size, int array[], int index, int sum)
{
if(size>index)
{
sum=sum+array[index];
index++;
recursive_function( size, array, index, sum);
}
cout<<"from the recursive function"<<endl;
cout<<"------"<<endl;
cout<<"new sum= "<< sum<<endl;
getch();
return 0;
}
#include <iostream>
#include<conio.h>
<conio.h is not a standard header, i.e. it is not available with all compilers, and you don't need it.
To see the result output of your program:
run it from the command line, or
in Visual Studio run it via keypress [Ctrl F5] (no debugging), or
set a breakpoint on the closing brace of main, and run it under a debugger (in Visual Studio e.g. via keypress [F5]).
#include <stdlib.h>
As far as I can see you’re not using anything from this header. However, it does provide the symbolic constants EXIT_SUCCESS and EXIT_FAILURE, which are intended for return statement in main. E.g., it can be more clear to write EXIT_SUCCESS there than to write 0, because many folks misunderstand what 0 means in this context.
using namespace std;
This is OK for a short program or within a namespace.
However, keep in mind that short programs very often end up as not-so-short programs.
And then a using namespace std; can easily cause name collisions, in particular with the name std::distance.
//headers of the thre functions
int random_value(int array[], int size);
int iterative_function (int array[], int size, int sum);
int recursive_function ( int size, int array[], int index, int sum);
Although it is partly a matter of preference, there is no advantage in forward-declaring the functions before main, it is more work, and it sometimes causes problems when the forward declarations don’t quite match the definitions – as with any unnecessary redundancy, violations of the DRY principle (Don’t Repeat Yourself).
Instead, just place the function definitions before main.
That way it is also much easier to see what refers to what, because functions that are used by others then necessarily come before those other functions.
int main()
{
int size;int array[size]; int sum=0;
This should not compile, because in C++ only a dynamically allocated array can have a size that is unknown at compile time.
However, C99 supports “variable length arrays” a.k.a. VLAs with the above syntax, and as a language extension the g++ compiler supports that.
On the third and gripping hand, even with the g++ language extension the above declares an array of indeterminate length, because the size variable has not been initialized and has an indeterminate value.
With the g++ compiler that value is most likely 0, but it can easily be any other value.
To turn off the g++ VLA language extension, and some other language extensions, use the following g++ options:
-pedantic -std=c++0x -Wall
For standard C++, instead of a C99 VLA you should use a C++ std::vector<int>.
In order to get a declaration of the std::vector class template, include the standard library header <vector>.
int index=0;
cout<<"enter the size of the array"<<endl;
cin>>size; //enter the size ofthe array...
When you're using a std::vector, then here, knowing its size, would be the place to declare that vector.
Or, if declared earlier, here would be the place to resize it.
random_value(array, size);
This would better be a function that returned a vector of random values.
You would then use that to initialize the declared vector.
iterative_function (array, size, sum);
recursive_function ( size, array, index, sum);
getch();
Regarding the getch() call, see the above comments about <conio.h>.
return 0;
Regarding the value 0 here, see the above comments about <stdlib.h>.
}
int random_value(int array[], int size)
{ cout<<"here is the value returned by rand()"<<endl;
for(int i=0;i<size;i++)
{ array[i]=( rand() % (0-2));
Here you have Undefined Behavior, accessing elements of a possibly zero-size array.
cout<<array[i]<<endl;
}
}
int iterative_function (int array[], int size, int sum)
{
int i,j, number, value; i=0;
cout<<"from the iterative function"<<endl;
cout<<"------"<<endl;
for(i=0;i<size;i++)
sum=sum+array[i];
Here you are again invoking Undefined Behavior, often called just “UB”, by accessing non-existing array elements.
In addition, even if the array had been of non-zero size, it has not been initialized and so would contain just zeroes or arbitrary values (by the Holy Standard called “indeterminate values”).
cout<<"sum of the array="<<sum<<endl;
getch();
See the above comment about <conio.h>.
return 0; //exit the function. Program terminated succesfully.
}
There is no point in letting the above function always return the same value. From an information-theoretical perspective, that return value carries zero bits of information. Instead just let the function’s result value be void.
int recursive_function ( int size, int array[], int index, int sum)
{
if(size>index)
{
sum=sum+array[index];
index++;
recursive_function( size, array, index, sum);
}
Instead of incrementing the index, which is non-idiomatic and therefore difficult to spot for experienced readers, just use index + 1 in the recursive call.
It is a good idea to add const to just about every declaration where it is possible.
That would, for example, have forced you to use index + 1. :-)
cout<<"from the recursive function"<<endl;
cout<<"------"<<endl;
cout<<"new sum= "<< sum<<endl;
getch();
See the above comment about <conio.h>.
return 0;
See the above comment about function always returning the same value.
}
Summing up, with all the Undefined Behavior it is just happenstance if things appear to work.
Fix the UB's (in particular replace C99 VLA with std::vector) first of all, then perhaps ask new question if it still does not work as it should. ;-)
You create your array using size but it's initialized AFTER that. You simply get random stuffs...
Declare int pointer, read size, allocate the array with new then try again (do not forget to delete).
First of all the array that you've declared is of unknown size, declare the array after getting input for size
Remember that in recursive_function() it calls itself many times - and every time it is called (either by main() or by itself) it will run all commands in its body (since you never return early)... now can you see a problem with the getch() in there?