4

I have an assignment to make a function that sort array that going down and then going up (for example: 9, 8, 7, 6, 5, 7, 11, 13) to array that going down all the way (for example: 13, 11, 9, 8, 7, 7, 6, 5).

I wrote this in online compiler (programiz), but it just doesn't work for me.

#include <stdio.h>
#include <stdlib.h>
#define N 10

void sort_dec_inc(int a[], int n) {
  int pivot, i, q = 0;
  int c[n];
  for (i=0; i<n; i++) {
      c[i] = 0;
  }
  for (i=0; i<n-1; i++) {
      if (a[i]<a[i+1]) {
          pivot=i+1;
          break;
      }
  }
  if (pivot == n-1) {
      return;
  }

  for (i=0; i<pivot && n>=pivot; q++) {
      if (a[i]>=a[n]) {
          c[q] = a[i];
          i++;
      }
      else {
          c[q] = a[n];
          n--;
      }
   }
   
   
   if (n==pivot) {
       while(i<pivot) {
           c[q] = a[i];
           q++;
           i++;
       }
   }
   else {
       while (n>=pivot) {
           c[q] = a[n];
           q++;
           n--;
       }
   }
   
   for(i=0; i<n; i++) {
       a[i] = c[i];
   }
   
   
}

int main()
{
    int num_arr[N] = {9, 7, 5, 3, 1, 2, 4, 6, 8, 10};
    sort_dec_inc(num_arr, N);
    int i;
    for(i = 0; i < N; i++) {
        printf("%d ", num_arr[i]);
    }

    return 0;
}

output (most of the times) : 9 7 5 3 1 2 4 6 8 10

Sometimes the output is different, for example: (410878976 10 9 8 1 2 4 6 8 10 )

If someone can answer in simple code its the best, I don't understand yet all the options in C.

(I'm sorry if its a clumsy code, I'm new for this.) thanks a lot!

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Alfa Hores
  • 347
  • 2
  • 10
  • 2
    The compiler issues some warnings, please check them out. The most basic one is *uninitialized local variable `q` used.* – Weather Vane Jul 25 '22 at 16:40
  • @WeatherVane it doesn't show me any warning... – Alfa Hores Jul 25 '22 at 16:42
  • 2
    Then please enable compiler warnings. For example with MS VC `-W3` – Weather Vane Jul 25 '22 at 16:42
  • 1
    [Turn up your warnings](https://godbolt.org/z/34PE5bv3T). – WhozCraig Jul 25 '22 at 16:44
  • @WeatherVane I fixed the errors, but it still doesn't work. – Alfa Hores Jul 25 '22 at 17:55
  • 1
    There is still a warning that I [mentioned](https://stackoverflow.com/questions/73112649/how-to-sort-an-array-that-going-down-and-then-going-up-to-array-that-going-down?noredirect=1#comment129128188_73112649). Local variables have an indeterminate value until explicitly given one. Perhaps you need `q = 0` but I can't guarantee that will solve the problem... and in fact, when I run the corrected code, the program runs but does not sort the array. – Weather Vane Jul 25 '22 at 17:59
  • 1
    `for (i=0; i<=n; i++)` is incorrect: off by one. It will break the array bounds. Try `for (i=0; i – Weather Vane Jul 25 '22 at 18:02
  • @WeatherVane I made those changes, but it still doesn't work. – Alfa Hores Jul 25 '22 at 18:09
  • @WeatherVane Did u understand what I tried to do? It make sense or I'm far from the solution? – Alfa Hores Jul 25 '22 at 18:11
  • 1
    No, I didn't follow the logic, but I can see that in some cases `pivot` won't get initialised. I suggest you follow it though with a debugger. – Weather Vane Jul 25 '22 at 18:12
  • 2
    Normally, sort functions take in data in any arbitrary (random) sequence and produce the sorted output. It isn't clear to me how much use you can make of the shape of the input. Your code finds the end of the descending sequence, and then uses a merge of the ascending portion with the descending portion, but it is unlikely to be faster than simply sorting the whole data set (and it's fragile). Measure the performance, but you'll need much bigger data sets (hundreds, if not thousands, of elements in the array to be sorted). And that means you'll need to worry about the VLA in the sort function. – Jonathan Leffler Jul 25 '22 at 18:23
  • 2
    Zeroing the `c` array should be unnecessary (and is a modest performance overhead). You're using O(N) extra memory, so the memory consumption is high. And you create the output in the array `c` and then copy that back to `a` — that is moderately expensive. Many sorts would not need O(N) extra memory. Your code is likely to break if the input is not in the shape you expect — that's what I mean by 'fragile'. – Jonathan Leffler Jul 25 '22 at 18:26
  • @JonathanLeffler Thanks for the explanation. (just say that I can know for sure the array would look like he looks because its part of the question) – Alfa Hores Jul 25 '22 at 18:43
  • 1
    The shape of the input (descending followed by ascending) allows the data to be sorted in O(N) time with O(N) extra space, using a single pass of a merge sort. You need three indexes: `left`, `right` and `output`. `left` starts at 0, and increments. `right` starts at `n-1` and decrements. `output` is the index into the `c` array. If `a[left] >= a[right]` copy `a[left]` to the `c` array and increment `left`. Otherwise, copy `a[right]` and decrement `right`. When `left` and `right` meet in the middle, you're done. – user3386109 Jul 25 '22 at 18:43
  • 1
    @user3386109 Hey thank u!!! this is basically what I tried to do, but I wrote it very clumsy – Alfa Hores Jul 25 '22 at 18:46
  • 1
    @AlfaHores You had the right idea. This technique (two indexes into the same array) is seen often enough that I assuming your professor wants you to become familiar with it. Best of luck! – user3386109 Jul 25 '22 at 18:50

3 Answers3

2

For starters it is a bad idea to define an auxiliary variable length array. Such an approach is unsafe because the program can report that there is no enough memory to allocate the array.

At least this code snippet

for (i=0; i<n-1; i++) {
    if (a[i]<a[i+1]) {
        pivot=i+1;
        break;
    }
}
if (pivot == n-1) {
    return;
}

contains a logical error.

Consider an array that contains only two elements { 1, 2 }. In this case a[0] is less than a[i+1] that is than a[1]. So the condition of the if statement

if (pivot == n-1) {
    return;
}

evaluates to logical true and the function returns the control though the array was not sorted in the descending order. It stays unchanged.

Or consider this code snippet

  if (a[i]>=a[n]) {
      c[q] = a[i];
      i++;
  }

The expression a[n] accesses memory beyond the array that results in undefined behavior.

A straightforward approach is to use the method insertion sort.

Here is a demonstration program.

#include <stdio.h>
#include <string.h>

void insertion_sort( int a[], size_t n )
{
    size_t i = 1;

    while ( i < n && !( a[i-1] < a[i] ) ) i++;

    for ( ; i < n; i++ )
    {
        size_t j = i;

        while ( j != 0 && a[j-1] < a[i] ) --j;

        if ( i != j )
        {
            int tmp = a[i];
            memmove( a + j + 1, a + j, ( i - j ) * sizeof( int ) );
            a[j] = tmp;
        }
    }
}

int main( void )
{
    int a[] = { 9, 7, 5, 3, 1, 2, 4, 6, 8, 10 };
    const size_t N = sizeof( a ) / sizeof( *a );

    for ( size_t i = 0; i < N; i++ )
    {
        printf( "%d ", a[i] );
    }
    putchar( '\n' );

    insertion_sort( a, N );

    for ( size_t i = 0; i < N; i++ )
    {
        printf( "%d ", a[i] );
    }
    putchar( '\n' );
}

The program output is

9 7 5 3 1 2 4 6 8 10 
10 9 8 7 6 5 4 3 2 1 
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
2

Solution based on the comments below:

#include <stdio.h>
#include <stdlib.h>
#define N 10

void sort_dec_inc(int a[], int n) {
  int left, i = 0;
  int right = n-1;
  int c[n];
  while (i<n) {
      if (a[left] >= a[right]) {
          c[i] = a[left];
          left++;
      }
      else {
          c[i] = a[right];
          right--;
      }
      i++;
  }
  
  for(i=0; i<n; i++) {
       a[i] = c[i];
   }
   
}

int main()
{
    int num_arr[N] = {9, 7, 5, 3, 1, 2, 4, 6, 8, 10};
    sort_dec_inc(num_arr, N);
    int i;
    for(i = 0; i < N; i++) {
        printf("%d ", num_arr[i]);
    }

    return 0;
}

output: 10 9 8 7 5 5 4 3 2 1

1

I would recommend a bubble sort. It is an easy way to sort numbers in numerical order:

for (int i = 0; i < quant; i++)
{
  for (int j = 0; j < quant-1; j++)
  {
    if (Array[j] < Array[j + 1])
    {
      int temp = Array[j];
      Array[j] = Array[j + 1];
      Array[j + 1] = temp;
    }
  }
}

quant is the quantity of numbers you want to sort. Don't forget to define an integer array with length quant for the sorting process.

To access the array, just use a for loop to return all the results.

Daniel Walker
  • 6,380
  • 5
  • 22
  • 45