Wrong output from insertion sort - c

I get the wrong output when I execute my program, and I have no clue to what might be causing it.
As you can se below I have an array. However when executing the program I get the output:
array[0]=3
array[1]=1
array[2]=1
array[3]=5
array[4]=5
array[5]=8
Obviously it's not my expected output which would be {1,3,4,5,7,8}. What am I doing wrong?
#include <stdio.h>
#include <stdlib.h>
#define l 6
void isnertionSort(int array[]);
int main(void)
{
int array[l]={3,4,1,7,5,8};
for(int i=0; i<l;i++) {
printf("array[%d]=%d\n", i, array[i]);
}
printf("\n");
isnertionSort(array);
for(int i=0; i<l; i++){
printf("array[%d]=%d\n", i, array[i]);
}
return 0;
}
void isnertionSort(int array[])
{
int j,key;
for(int i =1;i<l;i++){
key = array[i];
j = i -1;
while(j>0 && array[j]>key){
array[j+1]=array[i];
j--;//j=j-1
}
array[j+1]= key;
}
}

Your inner loop has two minor bugs.
while(j >= 0 && array[j]>key) { /* j> 0 changed to j>=0 */
array[j+1]=array[j]; /* changed from i to j */
j--;
}
It's fairly straight-forward to debug if you compare your implementation with insertion sort algorithm. It would also help if you indent your code so that these sort of bugs can be spotted more easily.

For starters neither declaration from the header <stdlib.h> is used in the program. So the directive
#include <stdlib.h>
may be removed.
It is much better to use capital letters for #defined names. For example
#define N 6
It is difficult to distinguish low case letter l and 1 for the reader of the code.
You should write a general sorting function instead of a function that can accept arrays with only fixed 6 elements. So the function should be declared with two parameters as for example
void isnertionSort( int array[], size_t n );
This loop
while(j>0 && array[j]>key){
array[j+1]=array[i];
j--;//j=j-1
}
1) does not touch the elements of the array with the index equal to 0 and 1 and 2) sets all elements that are greater than key to key because key and array[i] are the same value.
array[j+1]=array[i];
^^^^^^^^
Taking all this into account the program can look the following way
#include <stdio.h>
#define N 6
void isnertionSort( int array[], size_t n );
int main(void)
{
int array[N] ={ 3, 4, 1, 7, 5, 8 };
for ( size_t i = 0; i < N; i++ )
{
printf( "array[%zu] = %d\n", i, array[i] );
}
putchar( '\n' );
isnertionSort( array, N );
for ( size_t i = 0; i < N; i++ )
{
printf( "array[%zu] = %d\n", i, array[i] );
}
putchar( '\n' );
return 0;
}
void isnertionSort( int array[], size_t n )
{
for( size_t i = 1; i < n; i++ )
{
size_t j = i;
int value = array[i];
for ( ; j != 0 && value < array[j-1]; --j )
{
array[j] = array[j-1];
}
if ( j != i ) array[j] = value;
}
}
The program output is
array[0] = 3
array[1] = 4
array[2] = 1
array[3] = 7
array[4] = 5
array[5] = 8
array[0] = 1
array[1] = 3
array[2] = 4
array[3] = 5
array[4] = 7
array[5] = 8

Related

C function to sort part of an array not producing any output

I have an assignment to modify the selection sort to sort all of the values on the odd positions of an array in ascending order and to sort all of the values on the even positions in descending order. I am currently working on the oddSort function
void oddSort(int arrSize, int arr[]){
int i;
int lastOdd;
int currentMin;
lastOdd = findLastOdd(arrSize);
for(i=0; i<lastOdd; i+=2){
if(i=0){
currentMin = arr[i];
}
else if (arr[i] < currentMin){
swap(&arr[i], &currentMin);
}
}
}
but, when I try to apply this function to an array and print the output for it the compiler returns nothing.
int main(){
int arrayOne[10] = {246, 101, 223, 228, 1, 249, 99, 111, 191, 126};
int i;
oddSort(10, arrayOne);
for(i=0; i<10; i++){
printf("%d ", arrayOne[i]);
}
return 0;
}
My pseudocode for the evenSort function is similar to the oddSort function so I will assume that that won't work either. I checked the swap and findLastOdd functions independently and they work, so I am sure that there is something wrong with the oddSort function itself. Any ideas as to what?
edit: here are the rest of the user defined functions in my code
int findLastOdd(int someNumber){//to give the oddSort function a stopping point
if(someNumber % 2 == 0){
return someNumber - 1;
}
else{
return someNumber;
}
}
int findLastEven(int someNumber){//to give the evenSort function a starting point
if(someNumber % 2 == 0){
return someNumber;
}
else{
return someNumber - 1;
}
}
void swap (int* a, int* b){// swaps two array elements using pointers
int temp;
temp = *a;
*b = *a;
*b = temp;
}
For starters there is no need to split the function that sorts the array into two separate functions.
Within the function oddSort in the if statement
if(i=0){
you are using the assignment = operator instead of the comparison operator ==. And moreover odd indices start from 1 not from 0.
And it is not enough to use only one loop to sort an array using the selection sort method.
Even the condition in your single for loop
for(i=0; i<lastOdd; i+=2){
is incorrect because the value of the index lastOdd can be a valid index position of an element of the array.
And the function swap contains a typo. Instead of
int temp;
temp = *a;
*b = *a;
*b = temp;
there must be
int temp;
temp = *a;
*a = *b;
*b = temp;
Here is a demonstration program that shows how the sorting function can be written.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void OddEvenSort( int a[], size_t n )
{
for ( size_t i = 0; i < n; i++ )
{
size_t target = i;
for ( size_t j = i; ++j < n && ++j < n ; )
{
if ( i % 2 == 0 )
{
if ( a[target] < a[j] ) target = j;
}
else
{
if ( a[j] < a[target] ) target = j;
}
}
if ( target != i )
{
int tmp = a[i];
a[i] = a[target];
a[target] = tmp;
}
}
}
int main( void )
{
enum { N = 20 };
int a[N];
srand( ( unsigned int )time( NULL ) );
for ( size_t i = 0; i < N; i++ )
{
a[i] = rand() % N;
}
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
OddEvenSort( a, N );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
}
The program output might look like
11 11 14 4 11 17 18 4 12 6 16 8 15 10 9 7 13 9 4 15
18 4 16 4 15 6 14 7 13 8 12 9 11 10 11 11 9 15 4 17
As you can see values in even positions are sorted in the descending order
18 16 15 14 13 12 11 11 9 4
and values in odd positions are sorted in the ascending order
4 4 6 7 8 9 10 11 15 17
Notice that in your function oddSort you seemingly sorting the odd numbers of your array in o(logn) run time, but it's Not possible to sort o(n/2)=o(n) elements in o(logn). In fact the minimum run time for sorting is o(nlogn).
int findLastOdd(int someNumber){//to give the oddSort function a stopping point
if(someNumber % 2 == 0){
return someNumber - 1;
}
else{
return someNumber;
}
}
void swap (int* a, int* b){// swaps two array elements using pointers
int temp;
temp = *a;
*a = *b;
*b = temp;
}
int findMinValue(const int* arr, int startIndex, int arrSize) {
int min = startIndex;
for (int i = startIndex; i < arrSize; i += 2) {
if (arr[i] < arr[min]) min = i;
}
return min;
}
void oddSort(int arrSize, int* arr){
int i;
int lastOdd;
int currentMin;
lastOdd = findLastOdd(arrSize);
for(i=1; i<lastOdd; i+=2){
currentMin = findMinValue(arr, i, arrSize);
swap(&arr[currentMin], &arr[i]);
}
}
int main(){
int arrayOne[10] = {246, 101, 223, 228, 1, 249, 99, 111, 191, 126};
int i;
oddSort(10, arrayOne);
for(i=0; i<10; i++){
printf("%i: %d\n", i, arrayOne[i]);
}
return 0;
}
In the swap function, you mixed up the variables. Also you had a syntax error in the if statement in oddSort(). You assigned 0 to i instead of actually checking if i is equal to zero with ==.
In Selection Sort, you need to iterate the array and find the smallest value you can find. You return the index of that element and then you swap the current element with the smallest one. You forgot this step apparently, so I made the function for you findMinValue().
You can finish off the code yourself and make it prettier/get rid of some inefficiencies, but the code I posted above works (on my machine :^)).

main.c:36:9: error: array size missing in ‘num’ int num[]; Why am I getting error for array size although i have given array size in code?

#include <stdio.h>
int removeduplicates(int arr[],int n){
int j=0;
int temp[15];
if(n==0 || n==1){
return n;
}
for(int i=0;i<n-1;i++){
if(arr[i]!=arr[i+1]){
temp[j++]=arr[i];
}
temp[j++]=arr[n-1];
}
for(int i=0;i<j;i++){
arr[i]=temp[i];
}
return j;
}
int main(){
int n;
int num[];
num[]= {1,2,3,3,4,4,5,5,5};
n= sizeof(num)/sizeof(num[0]);
n=removeduplicates(num,n);
printf("%d",n);
return 0;
}
Here in this question I was writing a code to remove duplicates from a sorted array. But I am getting the following error although I defined the array size and although I provided the array size.
main.c:36:9: error: array size missing in ‘num’
int num[];
^~~
main.c:37:9: error: expected expression before ‘]’ token
num[]= {1,2,3,3,4,4,5,5,5};
This code snippet
int num[];
num[]= {1,2,3,3,4,4,5,5,5};
is syntactically incorrect.
Instead write
int num[] = {1,2,3,3,4,4,5,5,5};
Also within the function this declaration with the magic number 15
int temp[15];
and this statement
temp[j++]=arr[n-1];
in the substatement of this for loop
for(int i=0;i<n-1;i++){
if(arr[i]!=arr[i+1]){
temp[j++]=arr[i];
}
temp[j++]=arr[n-1];
}
do not make a sense.
To remove duplicates there is no need to define an auxiliary array.
The function can be written for example the following way as shwon in the demonstrative program below.
#include <stdio.h>
size_t removeduplicates( int arr[], size_t n )
{
size_t m = 0;
for ( size_t i = 0; i != n; )
{
if ( m != i )
{
arr[m] = arr[i];
}
++m;
while ( ( ++i != n && arr[i] == arr[i-1] ) );
}
return m;
}
int main(void)
{
int num[]= { 1, 2, 3, 3, 4, 4, 5, 5, 5 };
const size_t N = sizeof( num ) / sizeof( *num );
for ( size_t i = 0; i != N; i++ )
{
printf( "%d ", num[i] );
}
putchar( '\n' );
size_t m = removeduplicates( num, N );
for ( size_t i = 0; i != m; i++ )
{
printf( "%d ", num[i] );
}
putchar( '\n' );
return 0;
}
The program output is
1 2 3 3 4 4 5 5 5
1 2 3 4 5

How can I print the number of unique elements instead of show the elements itself in my code?

I want to print the number of unique elements instead of show the elements For example show 4. Means we have 4 unique elements
#include<stdio.h>
#define max 100
int ifexists(int z[], int u, int v)
{
int i;
for (i=0; i<u;i++)
if (z[i]==v) return (1);
return (0);
}
void main()
{
int p[max], q[max];
int m;
int i,k;
k=0;
printf("Enter length of the array:");
scanf("%d",&m);
printf("Enter %d elements of the array\n",m);
for(i=0;i<m;i++ )
scanf("%d",&p[i]);
q[0]=p[0];
k=1;
for (i=1;i<m;i++)
{
if(!ifexists(q,k,p[i]))
{
q[k]=p[i];
k++;
}
}
printf("\nThe unique elements in the array are:\n");
for(i = 0;i<k;i++)
printf("%d\n",q[i]);
}
https://onlinegdb.com/Bk3tvQMpw
Sort the array then iterate through the elements and print out if the current element is different than the last:
int cmpint(const void *a, const void *b) {
return *(int *) a) < *(int *) b :
-1 ?
(
*(int *) b) < *(int *) a ?
1 :
0
);
}
int main() {
/* ... */
qsort(p, m, sizeof(*p), cmpint);
int n = 0;
for(int i = 0; i < m; i++) {
if(!i || p[i-1] != p[i]) n++;
}
printf("Number of unique elements: %d\n", n);
}
where p is your now sorted array and length is m as per example code. As qsort is expected O(m *log(m)) so will this aglorithm. If you don't sort the array it will be O(m^2) due to m linear searches.
If I have understood the question correctly what you need is to count unique elements in an array using a function and without defining an auxiliary array. That is there is no need to output the unique elements themselves.
In this case the corresponding function can look the following way as it is shown in the demonstrative program below.
#include <stdio.h>
int is_unique( const int a[], size_t n, int value )
{
while ( n != 0 && a[ n - 1 ] != value ) --n;
return n == 0;
}
int main(void)
{
int a[] = { 1, 2, 3, 3, 2, 1 };
const size_t N = sizeof( a ) / sizeof( *a );
size_t count = 0;
for ( size_t i = 0; i < N; i++ )
{
count += is_unique( a, count, a[i] );
}
printf( "There are %zu unique elements in the array.\n", count );
return 0;
}
The program output is
There are 3 unique elements in the array.
If you do not want to define one more function to count unique elements in an array then just move the loop in the function shown in the above demonstrative program inside main.
Here you are.
#include <stdio.h>
int main(void)
{
int a[] = { 1, 2, 3, 3, 2, 1 };
const size_t N = sizeof( a ) / sizeof( *a );
size_t count = 0;
for ( size_t i = 0; i < N; i++ )
{
size_t j = i;
while ( j != 0 && a[j - 1] != a[i] ) --j;
count += j == 0;
}
printf( "There are %zu unique elements in the array.\n", count );
return 0;
}
The program output is the same as shown above that is
There are 3 unique elements in the array.
Pay attention to that according to the C Standard the function main without parameters shall be declared like
int main( void )
instead of
void main()

Sorting array algorithm error

Hi I wrote this sorting algorithm and I'm not sure why I'm getting the following error: "member reference base type 'int' is not a structure or union"
void sort(float avg_dist, cg[]){
int i,j,t;
for(i=1; i<=cg[i]-1; i++)
for(j=1; j<=cg[i]-i; j++)
if(cg[j-1].avg_dist >= cg[j].avg_dist){
t = cg[j-1];
cg[j-1] = cg[j];
cg[j] = t;
}
}
cg is an int array.
You can't access a "member" of an int, as in
cg[j-1].avg_dist
I'm not sure what you're trying to do. Maybe multiply ?
cg[j-1] * avg_dist
It's not the problem, but you're (perhaps intentionally) omitting the type specifier in your function
void sort(float avg_dist, cg[]){
C is defaulting to an int array type, which of course, renders cg[j].avg_dist syntactically invalid. (In reality you probably want to multiply by avg_dist, use * rather than the member selection operator .).
This should give you a clear Idea:
#include <stdio.h>
void sortArray(int *array, int length){
int i,j, k, temp;
for (i = 0 ; i < length-1; i++){
for (k = 0 ; k < length-i-1; k++){
if (array[k] > array[k+1]){
temp = array[k];
array[k] = array[k+1];
array[k+1] = temp;
}
}
}
printf("The result:\n");
for ( j = 0 ; j < length ; j++ ){
printf("%d ", array[j]);
}
}
int main(void){
int array[] = {1,4,2,-1,2,3,4,1,3,-1};
int length = sizeof array / sizeof array[0];
sortArray(array, length);
printf("\n");
return 0;
}
Output:
The result:
-1 -1 1 1 2 2 3 3 4 4

Combine or merge 2 array with loop or function

I'm new to the C world. I'm using Visual 2010. I need to create an array from 2 other arrays, or a function to merge them; I come from PHP so I'm sorry if this is stupid. I tested some loop without success..
a real example could be helpful:
int arrayA[5] = {3,2,1,4,5}
int arrayB[5] = {6,3,1,2,9}
And the printed expected output of the third arrayC should be :
arrayC {
[3][6]
[2][3]
[2][1]
[4][2]
[5][9]
}
A straightforward approach can look the following way
#include <stdio.h>
#define N 5
int main( void )
{
int a[N] = { 3, 2, 2, 4, 5 };
int b[N] = { 6, 3, 1, 2, 9 };
int c[N][2];
for ( size_t i = 0; i < N; i++ )
{
c[i][0] = a[i]; c[i][1] = b[i];
}
for ( size_t i = 0; i < N; i++ ) printf( "%d, %d\n", c[i][0], c[i][1] );
return 0;
}
The program output is
3, 6
2, 3
2, 1
4, 2
5, 9
If you want to write a function that will merge arrays of any size then it can look like
#include <stdio.h>
#include <stdlib.h>
#define N 5
int ** merge( int *a, int *b, size_t n )
{
int **c = malloc( n * sizeof( int * ) );
if ( c != NULL )
{
size_t i = 0;
for ( ; i < n && ( c[i] = malloc( 2 * sizeof( int ) ) ); i++ )
{
c[i][0] = a[i]; c[i][1] = b[i];
}
if ( i != n )
{
while ( i-- ) free( c[i] );
free( c );
c = NULL;
}
}
return c;
}
int main( void )
{
int a[N] = { 3, 2, 2, 4, 5 };
int b[N] = { 6, 3, 1, 2, 9 };
int **c;
c = merge( a, b, N );
if ( c != NULL )
{
for ( size_t i = 0; i < N; i++ ) printf( "%d, %d\n", c[i][0], c[i][1] );
for ( size_t i = 0; i < N; i++ ) free( c[i] );
free( c );
}
return 0;
}
The program output will be the same as shown above.
Really It's unclear to all. I had understood like this.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int arrayA[5] = {3,2,2,4,5};
int arrayB[5] = {6,3,1,2,9};
int arrayC[5][5];
int i,j;
for(i=0; i<5; i++)
{
int a = arrayA[i]*10 + arrayB[i];
arrayC[i][0] = a;
}
for(i=0; i<5; i++)
{
printf("%d ", arrayC[i][0]);
printf("\n");
}
return 0;
}
After your comment:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int arrayA[5] = {3,2,2,4,5};
int arrayB[5] = {6,3,1,2,9};
int arrayC[5];
int i,j;
for(i=0; i<5; i++)
{
arrayC[arrayA[i]] = arrayB[i];
}
for(i=0; i<5; i++)
{
printf("[%d %d]",arrayA[i], arrayC[arrayA[i]]);
printf("\n");
}
return 0;
}
Please edit your question and specify it (you can read https://stackoverflow.com/help/how-to-ask ).
If you know size of the array, you can create 2D array in that way:
int array[2][5] = { {2, 3, 4, 5}, {6, 3, 1, 2, 9} };
Also take a look to malloc function. This is how to create dynamic 2D array
# create array of two pointers
int **tab = (int**) malloc(sizeof(int*) * 2);
# create pointer to array
tab[0] = (int*) malloc(sizeof(int) * 5);
tab[1] = (int*) malloc(sizeof(int) * 5);
tab[0][0] = 3;
tab[0][1] = 2;
// ...
tab[1][0] = 6;
tab[1][1] = 3;
tab[1][2] = 1;
// ...
// remember to call free
free(tab[0]);
free(tab[1]);
free(tab);
Of course you should use for loop. I show you only how to create array. Please also take a look at this thread Using malloc for allocation of multi-dimensional arrays with different row lengths
you can do this in c++ if i get what you mean
#include <iostream>
using namespace std;
int main()
{
int arrayA[5] = {3,2,2,4,5};
int arrayB[5] = {6,3,1,2,9};
int arrayC[10];
int a=0;
int b=0;
bool use_a= true;
bool use_b = false;
for ( int i =0 ; i <10 ; i++ )
{
if(use_a){
arrayC[i]=arrayA[a];
use_a=false;
use_b= true;
a++;
}else if(use_b){
arrayC[i]= arrayB[b];
use_b=false;
use_a= true;
b++;
}
}
for(int i =0 ; i <10 ; i++)
cout<<arrayC[i];
return 0;
}

Resources