6

I have a two dimensional array and want to sort both rows depending on the order of the elements in the first row:

i start with:

row1: { 4, 3, 1, 5, 0}

row2: { 7, 8, 9, 1, 2}

and the result should be:

row1: { 0, 1, 3, 4, 5}

row2: { 2, 9, 8, 7, 1}

QUESTION: Is it possible to achieve this, by using the qsort() function?

Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
andreas
  • 117
  • 1
  • 7
  • Interesting question. I'm fairly sure the answer is 'No' (not directly). If you create appropriate auxilliary data structures, it can be done, but not directly on `int data[2][5] = { { 4, 3, 1, 5, 0 }, { 7, 8, 9, 1, 2 } };`. – Jonathan Leffler Sep 26 '13 at 15:52
  • you can sort the first row normally, but would need a different (custom) comparison function that uses the sorted row for other rows – jev Sep 26 '13 at 16:05
  • Similar problem in concept to what an excel spread sheet does when a sort is applied. i.e. sort done on one column moves all associated row data with the sorted element. The sort could be done this way if the array, say int X[r][c]; is stored as a real 2D rather than pointers: qsort could be applied to the first row, but the movements of that transposition would have to be stored, then, rather than applying qsort for the remainder of rows, apply the stored transposition to each other row. Which may be what @JonathanLeffler was referring to by "axilliary date structures"? – ryyker Sep 26 '13 at 16:51
  • Is there a bound on the size of your rows and the elements in each row? – sfstewman Sep 26 '13 at 17:15
  • no, just limited by the size of available memory. – andreas Sep 27 '13 at 21:27

2 Answers2

4

I think ,that way it could be done.

#include<bits/stdc++.h>
using namespace std;

int cmp(const void *a,const void *b) {
    return ((const int *)a)[0] - ((const int *)b)[0];
}

int main(int argc,char *argv[]){
    int list[10][2];
    printf("Before sorting\n");
    for(int i=0; i<10; i++){ 
        list[i][0] = rand()%31;
        list[i][1] = rand()%12;
        printf ("list[%d][0] = %d list[%d][1] = %d\n", i, list[i][0], i, list[i][1]);
    }
    printf("AFTER sorting\n");
    qsort(list,10,2*sizeof(int),cmp);
    for(int i=0; i<10; i++)
        printf ("list[%d][0] = %d list[%d][1] = %d\n", i, list[i][0], i, list[i][1]);
    return 0;
}

Output :

Before sorting
list[0][0] = 10 list[0][1] = 11
list[1][0] = 10 list[1][1] = 4
list[2][0] = 11 list[2][1] = 4
list[3][0] = 8 list[3][1] = 6
list[4][0] = 23 list[4][1] = 8
list[5][0] = 1 list[5][1] = 5
list[6][0] = 0 list[6][1] = 3
list[7][0] = 10 list[7][1] = 11
list[8][0] = 19 list[8][1] = 2
list[9][0] = 22 list[9][1] = 0
AFTER sorting
list[0][0] = 0 list[0][1] = 3
list[1][0] = 1 list[1][1] = 5
list[2][0] = 8 list[2][1] = 6
list[3][0] = 10 list[3][1] = 11
list[4][0] = 10 list[4][1] = 4
list[5][0] = 10 list[5][1] = 11
list[6][0] = 11 list[6][1] = 4
list[7][0] = 19 list[7][1] = 2
list[8][0] = 22 list[8][1] = 0
list[9][0] = 23 list[9][1] = 8
Shinora007
  • 53
  • 6
1

Not directly ...

... but qsort() could sort vectors by each vector's first element.

So the example data needed to be transposed and be converted into a fake 2d array, where the root pointer points to an array of pointers, with each pointer pointing to a row of the transposed original data.

qsort() then is passed the root pointer and the compare function compares on the vectors' first element. The vectors are passed to compare function by reference.

After sorting is done the result then needs to be converted the revers way as done prior to the call to qsort().

alk
  • 69,737
  • 10
  • 105
  • 255