Thomas Petit
Thomas Petit

Reputation: 57

Sorting an array in a specific way in the c language

I've been trying to sort an array of 26 randomized integer inputs in such a way that you first sort the odd integers and then you sort the even integers in an ascending order. What I've tried so far is using the selection sort algorithm and applying an if statement.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
    int arr[26], i, min, j, p;
    srand((unsigned)time(NULL));
    for (i = 0; i < 26; i++) {
        arr[i] = rand() % 100;
    }
    for (i = 0; i < 26; i++) {
        printf("%2d ", i);
    }
    puts("");
    for (i = 0; i < 26; i++) {
        printf("%2d ", arr[i]);
    }

    for (i = 0; i < 26; i++) {
        if (arr[i] % 2 != 0) {
            min = i;
            for (j = i + 1; j < 25; j++) {
                if (arr[j] < arr[min]) {
                    min = j;
                }
            }
            p = arr[i];
            arr[i] = arr[min];
            arr[min] = arr[i];
        } else {
            min = i;
            for (j = i + 1; j < 25; j++) {
                if (arr[j] < arr[min]) {
                    min = j;
                }
            }
            p = arr[i];
            arr[i] = arr[min];
            arr[min] = arr[i];
        }
    }

    puts("");
    for (i = 0; i < 26; i++) {
        printf("%2d ", arr[i]);
    }

    return 0;
}

That doesn't seem to be the correct way of doing it and I am a bit lost, since I'm a beginner. Could anyone provide any tips? Oh and apologies if my code looks like trash. Thank you for your answers

Upvotes: 1

Views: 351

Answers (2)

Lundin
Lundin

Reputation: 213810

The canonical way to do this in classic C is to use the qsort function and then provide a callback function specifying how to sort.

An ascending sort callback function to qsort could look like this:

int ascending (const void* o1, const void* o2)
{
  int a = *(const int*)o1;
  int b = *(const int*)o2;
  return a<b ? -1 : (a>b) ? 1 : 0;
}

You can then write a more specialized comparison function like this:

int odd_then_even (const void* o1, const void* o2)
{
  int a = *(const int*)o1;
  int b = *(const int*)o2;
  
  if((a^b)&1)            // one is odd and one is even
    return a&1 ? -1 : 1; // if a is the odd return -1, otherwise return 1
  else                   // both odd or both even
    return ascending(o1, o2);
}

Full example using 10 unique items:

#include <stdio.h>
#include <stdlib.h>

int ascending (const void* o1, const void* o2)
{
  int a = *(const int*)o1;
  int b = *(const int*)o2;
  return a<b ? -1 : (a>b) ? 1 : 0;
}

int odd_then_even (const void* o1, const void* o2)
{
  int a = *(const int*)o1;
  int b = *(const int*)o2;
  
  if((a^b)&1)            // one is odd and one is even
    return a&1 ? -1 : 1; // if a is the odd return -1, otherwise return 1
  else                   // both odd or both even
    return ascending(o1, o2);
}

void print_array (int array[10]);

int main (void)
{
  int array[10] = { 7,3,2,1,5,4,9,8,0,6 };
   
  qsort(array, 10, sizeof *array, ascending);
  print_array(array);

  qsort(array, 10, sizeof *array, odd_then_even);
  print_array(array);
}

void print_array (int array[10])
{
  for(int i=0; i<10; i++)
    printf("%d ", array[i]);
  puts("");
}

Output:

0 1 2 3 4 5 6 7 8 9
1 3 5 7 9 0 2 4 6 8

Upvotes: 1

MikeCAT
MikeCAT

Reputation: 75062

One approach is using a comparision function that says

  • Odd numbers are smaller than even numbers
  • If odd/evenness is same, compare the numbers

Also

  • Your code to swap elements is wrong. p should be assigned instead of arr[i] in the third step.
  • Your loops to search the minimum element are wrong because they are omitting the last element from the searching.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int cmp(int a, int b)
{
    if (a % 2 != 0 && b % 2 == 0) return -1;
    if (a % 2 == 0 && b % 2 != 0) return 1;
    if (a < b) return -1;
    if (a > b) return 1;
    return 0;
}

int main()
{
    int arr[26],i,min,j,p;
    srand((unsigned)time(NULL));
    for(i=0;i<26;i++){
        arr[i] = rand() % 100;
    }
    for(i=0;i<26;i++){
        printf("%2d ", i);
    }
    puts("");
    for(i=0;i<26;i++){
        printf("%2d ", arr[i]);
    }

    for(i=0;i<26;i++){
        min = i;
        for(j = i+1;j<26;j++){
            if(cmp(arr[j],arr[min])<0){
                min = j;
            }
        }
        p = arr[i];
        arr[i] = arr[min];
        arr[min] = p;
    }

    puts("");
    for(i=0;i<26;i++){
        printf("%2d ", arr[i]);
    }

    return 0;
}

Upvotes: 2

Related Questions