In which way i can find indexes of my random numbers and store them.
Example:
300, 2, 43, 12, 0, 1, 90
Values -> 0 1 2 12 43 90 300
Indexes -> 0 1 2 3 4 5 6
So. Can i store instead of my values their indexes?
Like This
300 2 43 12 0 1 90
6 2 4 3 0 1 5
And will it possible for negative numbers also?
This CAN be done simply if you're willing to use an array of "helper" struct
s...
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int val;
int in0;
int in1;
} pair_t;
// Two qsort() comparison functions
// NB: these may cause integer overrun for very large values
// OP advised to use longer 'comparison' evaluations if required
int cmpVal( const void *a, const void *b ) { return ((pair_t*)a)->val - ((pair_t*)b)->val; }
int cmpOrg( const void *a, const void *b ) { return ((pair_t*)a)->in0 - ((pair_t*)b)->in0; }
int main( void ) {
int i;
int unsort[] = { 300, 2, 43, 12, 0, 1, 90 };
const int n = sizeof unsort/sizeof unsort[0];
// Make a copy in unsorted order including original sequence.
pair_t *worken = malloc( n * sizeof *worken );
for( i = 0; i < n; i++ )
worken[i].val = unsort[i], worken[i].in0 = i;
// Sort that array by value ascending
qsort( worken, n, sizeof pair_t, cmpVal );
// Register this sequence with each array element
for( i = 0; i < n; i++ )
worken[i].in1 = i;
// Restore array's original sequence
qsort( worken, n, sizeof pair_t, cmpOrg );
// Copy the indices (of sorted version) to 'persistent' array.
// for demo, using a separate array instead of overwriting original
int sorted[n] = { 0 };
for( i = 0; i < n; i++ )
sorted[i] = worken[i].in1;
// Toss 'working' buffer.
free( worken );
// List original sequence
for( i = 0; i < n; i++ )
printf( "%4d", unsort[ i ] );
putchar( '\n' );
// List corresponding indices (as if sorted)
for( i = 0; i < n; i++ )
printf( "%4d", sorted[ i ] );
putchar( '\n' );
return 0;
}
Output
300 2 43 12 0 1 90
6 2 4 3 0 1 5
Trivial assignment loop to "replace values of original array with indices" left out for clarity...
The OP suggests the unsorted array is to have its values replaced(!) with indices indicating the sort order. (Taking that to mean, without using additional memory allocations.)
The following does as much with the proviso that array values are not near the top end of int
values (INT_MAX
).
For an array of n
integers, this blindly uses values of INT_MAX - n + 1
up to INT_MAX
for its purpose.
This version is processor intensive as it makes multiple passes over the data array.
#include <stdio.h>
#include <limits.h>
void show( int u[], size_t cnt ) { // Show current array values
for( size_t i = 0; i < cnt; i++ )
printf( "%4d", u[ i ] );
putchar( '\n' );
}
void oddSort( int u[], size_t cnt ) {
show( u, cnt );
// Successively find and replace highest values with decreasing large int values.
int peak = INT_MAX;
for( size_t set = 0; set < cnt; set++ ) {
int maxID = 0;
while( u[maxID] >= peak ) maxID++; // find first non-replaced value
for( size_t i = maxID + 1; i < cnt; i++ )
if( u[i] < peak && u[i] > u[maxID] )
maxID = i;
u[maxID] = peak--;
}
// transpose down to 0, 1, 2...
for( size_t i = 0; i < cnt; i++ )
u[i] -= peak + 1;
show( u, cnt );
}
int main( void ) {
{
int u[] = { 300, 2, 43, 12, 0, 1, 90 };
oddSort( u, sizeof u/sizeof u[0] );
}
putchar( '\n' );
{
// Test with negatives (coincidentally lowest value in first pos)
int u[] = { -256, 300, 2, 43, 12, 0, 1, 90 };
oddSort( u, sizeof u/sizeof u[0] );
}
return 0;
}
Output:
300 2 43 12 0 1 90
6 2 4 3 0 1 5
-256 300 2 43 12 0 1 90
0 7 3 5 4 1 2 6