Sorting an array with alternate smallest-largest values - c

Given an array I am required to sort it in such a way that the first element is the smallest value, the second element is the largest, the third element is the second smallest element and so on.
But my code just prints the original array and I am not able to figure out why. Any advice would be appreciated.
#include <stdio.h>
void swap(int m, int n);
int main()
{
int i,j,A[10],n;
printf ("enter the number of array elements\n");
scanf ("%d", &n);
for (i=0;i<n;i++){
scanf ("%d", &A[i]);
}
for (i=0;i<n;i++){
if (i%2 == 0){
for (j=i;j<n;j++){
if (A[j] < A[i]){
swap(A[i],A[j]);
}
}
}
else if (i%2 != 0){
for (j=i;j<n;j++){
if (A[j] > A[i]){
swap (A[i],A[j]);
}
}
}
}
for(i=0;i<n;i++){
printf ("%d\n", A[i]);
}
return 0;
}
void swap( int m, int n)
{
int temp;
temp = m;
m = n;
n = temp;
}

You need to pass by reference using pointers.
void swap( int *m, int *n)
{
int temp;
temp = *m;
*m = *n;
*n = temp;
}
and change your code to call it like this
swap (&A[i],&A[j]);
For a solution that doesn't use pointers you can use a MACRO like this;
#define swap(x,y) do{int t=(x);(x)=(y);(y)=t;}while(0);
swap(A[i],A[j]);
Just define this at the top of your file and remove the swap function and prototype. It's all about scope, because the MACRO is just a text replace it's in the correct scope to use A[i].

The first problem I notice in your program is your swap function. In your swap function, your parameters are primitive data types. Thus, the function creates copies of integers "m" and "n", and switches the values within the scope of the function swap. But as soon as the function returns, you haven't really swapped anything. To actually swap the values in the array that you created in main, you need to do a pass by reference(pass in pointers to the variable you are trying to swap). Modify your swap function like this:
void swap( int *m, int *n)
{
int temp;
temp = *m;
*m = *n;
*n = temp;
}
Then inside your main, pass in the address of that value in the array using the & operator(address of). Here is an example: swap (&A[i],&A[j]);
Other suggestions:
Format your code so there is space between your conditions in your for loops.
Add comments.

Related

Sorting an array in ascending order using pointers in C

I am writing a program that creates an array of random numbers from 1 to 100 and sorts them in ascending order. Below is working code that does this, but I need to modify it so that the "swap" function makes use of pointers. The call for the swap function should look like this: swap(???,???) where the two inputs are pointers. What is the best way to accomplish this?
#include<stdio.h>
#include<math.h>
int main()
{
void fillArray(int sizeArray, int array[sizeArray]);
void printArray(int sizeArray, int array[sizeArray]);
void sortArray(int sizeArray, int array[sizeArray]);
int sizeArray;
printf("\nSize of the array? ");
scanf("%d", &sizeArray);
int array[sizeArray];
fillArray(sizeArray,array);
sortArray(sizeArray, array);
printArray(sizeArray, array);
}
void fillArray(int sizeArray, int array[sizeArray])
{
int increment;
for(increment=0; increment<sizeArray; increment++)
{
array[increment]=rand()%101;
}
}
void sortArray(int sizeArray, int array[sizeArray])
{
void swap(int increment2, int increment, int array[]);
int increment, increment2, temp;
for (increment=0; increment < sizeArray ; increment++)
{
for (increment2=increment+1; increment2 < sizeArray; increment2++)
{
swap(increment2, increment, array);
}
}
}
void swap(int increment2, int increment, int array[])
{
int temp;
if (array[increment2] < array[increment])
{
temp=array[increment];
array[increment]=array[increment2];
array[increment2]=temp;
}
}
void printArray(int sizeArray, int array[sizeArray])
{
int increment=0;
printf("\nHere's the sorted array:\n");
while(increment<21)
{
printf("\n array[%d] is %d", increment, array[increment]);
increment++;
}
}
The output should look like this:
output
Define your swap function as below:
void swap(int *increment2, int* increment)
Modify your for loop where you call the swap function:
for (increment=0; increment < sizeArray ; increment++)
{
for (increment2=increment+1; increment2 < sizeArray; increment2++)
{
swap(array[increment2], array[increment]);
}
}
Then, modify your swap function:
void swap(int *increment2, int* increment)
{
int temp;
if (increment2 < increment)
{
temp= *increment2;
*increment2=*increment;
*increment2=temp;
}
}
You need to fix your function call for the parameters to be with pointers.
void swap(int *increment2, int* increment)
Then in your swap function you need
You will need to deference the integer*.
Example
int n1;
int* x = 100
n1 = *x;
You may need to
deference in the future example
Your function accepts pointers
void swap(int *increment2, int* increment)
If you have integers or another data type to reference them, refer to their address, you can perform & for referencing.
int i = 5;
int* x;
x = &i;
x is now an integer pointer to the address of i.
Your calling code needs to pass the address of the integers to compare and swap. Either of the following forms is acceptable, and they are equivalent.
swap(array+increment2, array+increment);
swap(&array[increment2], &array[increment]);
The first form takes the address of the first element (array) and adds the index (increment2) to get the address of the correct element.
The second version is more straightforward, perhaps. It uses the & address-of operator to take the address of array[increment2], which is the desired integer.
Your swap function need to be defined as follows:
void swap(int** p2, int** p1)
{
int temp;
if (*p2 < *p1)
{
temp=*p1;
*p1=*p2;
*p2=temp;
}
}
Note how the pointers are dereferenced with the * operator to get the integer values for comparison (and storage in temp).

Array pointers and functions

I have to write a C program to do the following:
Write a function that takes three arguments: a pointer to the first
element of a range in an array, a pointer to the element following
the end of a range in an array, and an int value. Have the function
set each element of the array to the int value.
My code is not working. Here is what I have so far. Any help is appreciated.
#include <stdio.h>
#include <iostream>
int listNumbers[3]{ 1,2,3 };
void Sorter(int *first, int * last, int *value);
int * first = &listNumbers[0];
int * last = &listNumbers[2];
int value;
int main() {
printf("your list numbers are:\n");
int i;
for (int i = 0; i < 3; ++i) {
printf("%d", listNumbers[i]);
}
printf("\n");
printf("enter an integer:\n");
scanf_s("%d", &value);
Sorter( first, last, &value);
printf("your new list numbers are:\n");
int j;
for (int j = 0; j < 3; ++j) {
printf("%d", listNumbers[j]);
}
printf("\n");
system("PAUSE");
return 0;
}
void Sorter(int *first, int * last, int *value) {
int i=0;
printf("value = %d\n", &value);
*first = value;
while (i <= *last) {
*(first + i) = value;
i++;
}
}
First, work out the different between the 2 pointers.
int count = last - first + 1;
The compiler will automatically divide by the size of an integer. We add 1 to make the range inclusive. Now just iterate through each element:
for (int i = 0; i < count; i++) {
first[i] = value;
}
Also, why are you passing the value as a pointer? This should just be a value.
void Sorter(int *first, int *last, int value) {
And when you call it...
Sorter(first, last, value);
Your Sorter function does not satisfy the problem criteria. The parameters are supposed to be two pointers into an array, and an int. Your function instead accepts three pointers.
You could nevertheless have made it implement at least the apparent spirit of the exercise, by using the value to which the third argument points as the fill value, but you don't do that. Instead you assign the pointer itself to each array element. That ought to at least elicit a warning from your compiler, and you ought not to be ignoring its warnings, especially when your code it not doing what you think it should.
Furthermore, the last pointer is expected to point to just past the last element to set, but you use it as if it points to an integer offset from the start pointer. This is almost the opposite of the previous problem: here, you need to use the pointer value itself, not the int to which it points.

Passing an array to a sort function in C language

#include<stdio.h>
#include<conio.h>
float smallest(int arr[],int k,int n);
void sort(int arr[],int n);
void main()
{
int arr[20],i,n,j,k;
clrscr();
printf("\nEnter the number of elements in the array: ");
scanf("%d",&n);
printf("\nEnter the elements of the array");
for(i=0 ; i < n ; i++)
{
printf("\n arr[%d] = ",i);
scanf("%d",&arr[i]);
}
sort(arr,n);
printf("\nThe sorted array is: \n");
for(i=0 ; i < n ; i++)
printf("%d\t",arr[i]);
getch();
}
int smallest(int arr[],int k,int n)//smallest function
{
int pos=k,small=arr[k],i;
for(i=k+1;i<n;i++)
{
if(arr[i]<small)
{
small=arr[i];
pos=i;
}
}
return pos;
}
void sort(int arr[],int n)//sorting function
{
int k,pos,temp;
for(k=0 ; k < n ; k++)
{
pos=smallest(arr,k,n);
temp=arr[k];
arr[k]=arr[pos];
arr[pos]=temp;
}
}
In the above program the sort function is being called from main but the return type of sort is void and it still returns the sorted array. As after sorting the array the function should return the sorted array back to the calling function to print the sorted array but the program runs perfectly. How is that happening?
When you declare
int arr[20];
you can say "arr is an array of 20 integers". But arr is a pointer to an integer as well, pointing to the first integer in a row of 20. So de-referencing *arr is an integer, the same as arr[0] in fact.
This means when you pass arr to a function you only pass a pointer to that function. The function in this case works on the (copied) pointer. But this very pointer points exactly to the same memory as your original arr declared in main(). And that's the reason why manipulating arr in sort() is in fact manipulating arr in main().
When passing an array as a parameter, this
int smallest(int arr[],int k,int n)
means exactly the same as
int smallest(int *arr,int k,int n)
For example
#include<iostream>
void printArray(int data[])
{
for(int i = 0, length = sizeof(data); i < length; ++i)
{
std::cout << data[i] << ' ';
}
std::cout << std::endl;
}
int main()
{
int data[] = { 5, 7, 8, 9, 1, 2 };
printArray(data);
return 0;
}
You will see that only the first 4 elements of the array are printed. The sizeof(data) returns a value of 4! That happens to be the size of the pointer used to pass the array to printArray().
First the array does not get copied. The pointer to the first element of the array is copied
First, there is no connection between any function argument what is, or is not passed using a return statement with an expression according to the function's return type.
While it is true that all parameter passing in C is by value - copy the value to a "local parameter variable" - nothing is assumed about what is to happen at the memory location a pointer is referencing. So, a function can make any changes in the calling environment, even without returning a value.
As to parameters declared as being aType name[]. this is merely syntactic sugar for const aType* name.

implementation of Cormen's HeapSort algorithm in C

I am trying to implement the Heap sort algorithm provided in Cormen. My code is as follows :
#include<stdio.h>
#include<conio.h>
void max_heapify(int *,int);
void build_max_heap(int *,int);
void heapsort(int *,int);
void swap(int,int);
int heapsize;
int main()
{
int *arr,n,i;
printf("Enter no. of elements = ");
scanf("%d",&n);
arr=(int *)malloc(sizeof(int)*n);
for(i=0;i<n;i++)
{
printf("Enter array elements = ");
scanf("%d",&arr[i]);
}
//heapsize = n;
heapsort(arr,n);
printf("\nAfter heapsort \n");
for(i=0;i<n;i++)
{
printf("%d ",arr[i]);
}
return 0;
}
void heapsort(int *arr,int len)
{
int i;
build_max_heap(arr,len);
for(i= len-1;i>=1;i--)
{
swap(&arr[0],&arr[i]);
heapsize = heapsize -1;
max_heapify(arr,0);
}
}
void max_heapify(int *arr,int i)
{
int l=2*i,r=2*i+1,largest;
if(l<heapsize && arr[l]>arr[i])
largest = l;
else
largest = i;
if(r<heapsize && arr[r]>arr[largest])
largest = r;
if(largest != i)
{
swap(&arr[i],&arr[largest]);
max_heapify(arr,largest);
}
}
void build_max_heap(int *arr,int len)
{
heapsize = len;
int i;
for(i =len/2;i>=0;i--)
{
max_heapify(arr,i);
}
}
void swap(int *a ,int *b)
{
int temp = *a;
*a= *b;
*b= temp;
}
I cannot figure out what exactly is wrong in my code. The array is not getting sorted.In fact the original array is getting printed. Where am I going wrong?
Your swapfunction takes the arguments by value. So the original values are copied and the copies are swapped instead of the originals.
swap( int *a, int *b)
1) Fix swap, you're passing by value. Which means after swap is called nothing was changed!
2) The max_heapify function is wrong. Your left and right child calculation is off by 1. When you swap, you swap an index with an array value, yikes.
3) heapsort for-loop is wrong. You should put the first element (largest one in the heap) to the last index of the current heap, decrease the size of heap so the last element is part of the sorted list and not the heap. Then you perculate down from the root, not from the last element. Should be:
for(i= len-1;i>=1;i--)
{
swap(arr[0],arr[i]);
heapsize = heapsize -1;
max_heapify(arr,0);
}
You observe that your array is not getting sorted at all. Try working up to a complete heap sort in increments. So, as a debugging technique, create a copy of this code and replace the heapsort with a bubble sort. (bubble sorts are much easier to code). Get the bubble sort to work, this includes passing parameters and print the array before and after the sort.
Then do the heap sort.
The algorithm listed in Cormen seems to have a mistake.
Simply change the following line in your code:
max_heapify(arr,0); \In heapsort function
with
build_max_heap(arr,heapsize);

Input array with recursively function without loops (.c)

I need to write a function, to input the size of array and allocate memory, and read (scanf) values to this array.
I wrote this function but it does not work:
void getss(int array[], int size)
{
int counter = 0;
if (size == 0)
return;
if (counter < size) {
scanf("%d", &array[i]);
counter++;
}
getss(array, size - 1);
}
It is not exactly clear what you are trying to achieve. But I would guess that your array parameter is not correct in the recursive call. Now all calls to getss get same array but different size. (Where does variable i come from? Variable counter does not have much use in posted code.)
I would assume that you need to update the array pointer to point to next element in array in the recursive call. In other words, pass address of second element in the array instead of the first element (current behaviour). That would be in line with the size-1 in the recursive call.
The implementation is trivial but is left as an exercise to the poster as this looks like homework to me.
You have unneeded variables. Is this what you are trying to accomplish:
The following will fill in the array so that the first value read with scanf() will be stored in the last element.
void getss(int array[], int size)
{
if (size == 0)
return;
scanf("%d", &array[size-1]);
getss(array, size - 1);
return;
}
The following will fill in the array so that the first value read with scanf() will be stored in the first element.
void getss(int array[], int size)
{
if (size == 0)
return;
scanf("%d", &array[0]);
getss(&array[1], size - 1);
return;
}
If you were to do this iteratively, how would you do it? I would assume something like this:
void getss(int array[], int size) {
int i;
for (i = 0; i < size; i++) {
scanf("%d", array[i]);
}
}
Our i there just serves to count our way through the array, so if we change our function slightly we can get rid of it:
void getss(int* array, int size) {
for (; size > 0; size--, array++) {
scanf("%d", array);
}
}
Now our "counter" is the size variable itself and instead of indexing in our array we just keep stepping forward our pointer to it.
Now this is in a perfect form to be turned into a recursive function. Instead of size-- and array++ we can pass the new values into another call to getss at the end of the function:
void getss(int* array, int size) {
if (size > 0) {
scanf("%d", array);
getss(array + 1, size - 1);
}
}
So our loop's terminating condition has moved into an if and instead of array++ and size-- we pass in array+1 and size-1 to our next call. It achieves the same result as looping but without an explicit loop construct.
Along with the other problems, what's the point of using counter? It is either 0 or 1 and never passed to the next call. Should it have been declared static?
#include <stdio.h>
#include <stdlib.h>
void getss(int* array, int size){
if (size == 0)
return;
scanf("%d", array);
getss(++array, size - 1);
}
int main(){
int *array;
int i, size;
printf("input array size:");
scanf("%d", &size);
array = (int*)malloc(sizeof(int)*size);
getss(array, size);
for(i=0;i<size;i++){
printf("array[%d]=%d\n", i, array[i]);
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
int a[100];
void input(int n)
{
if(n==0)
{
return;
}
input(--n);
cin>>a[n];
}
int main()
{
int n=4;
input(n);
for(int i=0;i<n;i++)
{
cout<<a[i]<<" ";
}
}
void getss(int array[], int size , int counter)
{
if (size == 0)
return;
if (counter < size) {
scanf("%d", &array[i]);
counter++;
}
getss(array, size - 1, counter);
}

Resources