1

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

4
  • 1
    I suggest you first partition the array, putting the odd number at one end of the array and the even at the other. Then find out where the split is, and sort them using standard qsort as two different arrays. Commented Jan 5, 2021 at 13:44
  • The comparator function for qsort can be easily arranged that first it tests the "evenness" of the two items, and if the same, their value. Only one qsort is needed. Commented Jan 5, 2021 at 13:47
  • @Someprogrammerdude Thank you a lot for your help. I'll give it a go using the qsort function to test it out Commented Jan 5, 2021 at 14:05
  • @Someprogrammerdude I doubt that would be more efficient than sorting them in place directly. You'd iterate over the same data over and over. I posted an example as answer. Commented Jan 5, 2021 at 14:29

2 Answers 2

2

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;
}
Sign up to request clarification or add additional context in comments.

2 Comments

And... a qsort alternative also works.
Thank you a lot. While I have some troubles understanding how exactly that function works, I think that with some time and practice I'll get it. Again appreciated a lot
1

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

11 Comments

Shouldn't ascending return 0 if a == b? As coded, it seems to violate the constraint on the comparison function: The contents of the array are sorted into ascending order according to a comparison function pointed to by compar, which is called with two arguments that point to the objects being compared. The function shall return an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second. I wonder if this could break qsort() with a carefully chosen dataset.
@chqrlie doesn't really matter since qsort puts them in an unspecified order in case they are equal. Not to be confused with bsearch.
It should not matter, but can you prove it? The stability argument seems only partially relevant.
7.22.5.2 "If two elements compare as equal, their order in the resulting sorted array is unspecified." Also, these functions pretends that no equal objects were found. I know of no sorting algorithm that somehow requires items to compare equal. qsort will likely either be implemented as quick sort or merge sort.
Pedantic: if((a^b)&1) is an OK test for 2's complement int, yet fails for that junkyard dinosaur with 1s' complement.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.