Thread: sort elements of 2D matrix by 1st column reference

  1. #1
    Registered User
    Join Date
    Mar 2009
    Posts
    114

    sort elements of 2D matrix by 1st column reference

    Hi everyone,

    I am writing a function that needs to sort the rows of a 2D matrix in ascending order.
    To so, I first wrote the function to treat a 1D array and, by analogy, tried to build one that takes an array of pointers as argument, but I am not sure where I am doing that wrong, since I am not getting the sorted array in return.

    I post my code below, I hope someone can help
    All the best
    cfd

    In the following code, *array[] that is passed is a 2D matrix of "lenght" rows and 6 columns:
    Code:
    void sortAscend(float *array[], int length)
    {
      int i, j, temp, test;
      
    	for(i = length - 1; i > 0; i--)
    	{
        test=0;
        	for(j = 0; j < i; j++)
        	{
        	  if(*array[1] > *(array[1]+1)) /* compare neighboring elements */
        	  {
        	    temp = *array[1];    	/* swap array[j] and array[j+1] */
        	    *array[1] = *(array[1]+1);
        	    *(array[1]+1) = temp;
        	    test=1;
        	  }
        	} /*end for j*/
        	if(test==0) break; /*will exit if the list is sorted!*/
    	} /*end for i*/
     }

  2. #2
    Making mistakes
    Join Date
    Dec 2008
    Posts
    476
    There are many sorting algrithms out there. If speed is not all important, try bubblesort. Else you might have a look at merge- or quicksort.

  3. #3
    Registered User
    Join Date
    Mar 2009
    Posts
    114
    Hi,

    Thanks for the hint; I will look into those then

    Best
    cfd

  4. #4
    Registered User
    Join Date
    Mar 2009
    Posts
    114
    I'm fairly certain you should be using your i and j variables in places other than just the two lines related to the for loops
    hi, I was thinking the same, although I wanted to be using the pointer arrays instead of a double loop

    Also, why am I not seeing this last reply inside the forum but only in my email? Is anything wrong with the forum?

    thanks

  5. #5
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Heh, heh... I deleted my post right before you posted yours. It's just bad timing.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  6. #6
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Brafil View Post
    There are many sorting algrithms out there. If speed is not all important, try bubblesort.
    Technically this is a (modified*) bubblesort. However, there are some syntax issues. The most obvious is that you use [1] as the subscript everywhere, and constantly use * to dereference "array". In the context of your function:

    array[x] refers to a row. No asterisk.
    array[x][y] would refer to a row element.

    You do not explain in your post what you actually intend to sort by: the total for the row, or the first element (or perhaps the second element, hence [1]?)

    This:
    Code:
    array[1]+1
    would be the location of array[1] plus a byte. You probably want:
    Code:
    array[x+1]
    However, this will be a problem since you start with the last element (length-1), meaning x+1 does not exist.

    A very useful thing to do here would be to use some printf statements in the loop to check the value of things to see if they refer to what you think they refer to, eg:
    Code:
    printf("temp = %f %f %f\n",temp[i][0],temp[i][1],temp[i][2]);fflush(stdout);
    *by virtue of the fact that you use a flag, "test"
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  7. #7
    Registered User
    Join Date
    Mar 2009
    Posts
    114
    Quote Originally Posted by MK27 View Post
    You do not explain in your post what you actually intend to sort by: the total for the row, or the first element (or perhaps the second element, hence [1]?)
    Hi MK27,

    Your reply is very helpful. To answer to your commented quoted above, some details here:
    Imagine that the first column of my 2D array (call it mat2d for now), contains values that must be sorted in an ascending order, and all the rows of every other columns must be movied accordingly, since each column is related to the first

    ex.:

    Code:
    300  4 6 7
    200 1 4 2
    10   5 7 32
    150 6 2 4
    must become:
    Code:
    10   5 7 32
    150 6 2 4
    200 1 4 2
    300  4 6 7
    meaning that the column that dictates is column 1, and all the others are moved accordingly. That is why I though of using an array of pointers instead of a 2D array

    Thanks again

  8. #8
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by cfdprogrammer View Post
    meaning that the column that dictates is column 1, and all the others are moved accordingly. That is why I though of using an array of pointers instead of a 2D array

    Thanks again
    There is nothing wrong with using pointers here. But three little notes:

    • the first element (ie, "column 1") of an array is 0, not 1
    • to sort by that element using your row pointers, use array[x][0], where x is the row number.
    • again, do not dereference "array" inside the function by placing an asterisk in front of it (this only indicates a pointer in a variable declaration).
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  9. #9
    Registered User
    Join Date
    Mar 2009
    Posts
    114
    Hi again MK27,

    Thanks for the hints; about the index 1 instead of zero it was done on purpose but I didn't realize that I didn't comment on that; I am allocating my arrays on a 1-index base instead of zero.

    For everything else, I will follow your suggestion and post it again if I find some porblem

    Thank you again for helping
    All the best!
    cfd

  10. #10
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You can't assign rows of arrays by simply using the = operator on them:
    Code:
    *temp = array[j][1];    /* swap array[j] and array[j+1] */
        	    array[j][1] = array[j+1][1];
        	    array[j+1][1] = *temp;
    And even if it did, what would that line up with what you did here:
    Code:
    temp = malloc((cols+1)*sizeof(float*));

    Quzah.
    Hope is the first step on the road to disappointment.

  11. #11
    Registered User
    Join Date
    Mar 2009
    Posts
    114
    Quote Originally Posted by quzah View Post
    You can't assign rows of arrays by simply using the = operator on them:
    Code:
    *temp = array[j][1];    /* swap array[j] and array[j+1] */
        	    array[j][1] = array[j+1][1];
        	    array[j+1][1] = *temp;
    And even if it did, what would that line up with what you did here:
    Code:
    temp = malloc((cols+1)*sizeof(float*));

    Quzah.
    Hi Quazah,
    thanks for replying.

    How am I supposed to assign rows of an array if I use a pointer in this way?

    Best,
    cfd

  12. #12
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Code:
    for each element in the row...
        temp[ element ] = here[ element ]
        here[ element ] = there[ elemenet ]
        there[ element ] = temp[ element ]
    The same way you normally swap variables, but you need to swap each element in the row by hand.


    Quzah.
    Hope is the first step on the road to disappointment.

  13. #13
    Registered User
    Join Date
    Mar 2009
    Posts
    114
    Perfect, it's now solved!

    thank you very much for helping

    Best,
    cfd

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Left Shift elements of a 2D array
    By w2look in forum C Programming
    Replies: 8
    Last Post: 01-23-2009, 12:13 AM
  2. how to initialize a char matrix with empty elements?
    By kobra_swe in forum C Programming
    Replies: 3
    Last Post: 08-22-2006, 05:28 AM
  3. What is a matrix's purpose in OpenGL
    By jimboob in forum Game Programming
    Replies: 5
    Last Post: 11-14-2004, 12:19 AM
  4. Very handy matrix functions - part 1
    By VirtualAce in forum Game Programming
    Replies: 8
    Last Post: 05-20-2004, 10:38 AM