0

I need to sort this large array of three doubles on Column 3... MAG:

double[,] StarList = new double[1000000, 3];

Access is like:

StarList[x, y++] = RA;

StarList[x, y++] = DEC;

StarList[x, y] = MAG;

Performance is important.

In-place would be nice, but not required.

I can convert the doubles to Int32 if its better and faster.

Thanks...

Anik Islam Abhi
  • 24,324
  • 8
  • 52
  • 74
JerryG
  • 3
  • 1
  • There is no difference in sorting 1 dimension array or third column of an array. Algorithm depends on the data you have and constraints. May be just use standart algorithms? – Giorgi Nakeuri Oct 26 '15 at 04:44

1 Answers1

3

The easy way: Multidimensional arrays are just not for that. You'd better consider alternative representation. For instance, the one dimensional array of the following struct would have exactly the same layout as yours:

struct StarInfo { public double RA, DEC, MAG; }

Declaration:

var StarList = new StarInfo[1000000];

Access:

StarList[x].RA = RA;
StarList[x].DEC = DEC;
StarList[x].MAG = MAG;

And can easily be sorted:

Array.Sort(StarList, (a, b) => a.MAG.CompareTo(b.MAG));

The hard way: If you still insist on using multidimensional array, here is what you can do.

First, use indirect sorting:

var sortIndex = new int[StarList.GetLength(0)];
for (int i = 0; i < sortIndex.Length; i++)
    sortIndex[i] = i;
Array.Sort(sortIndex, (a, b) => StarList[a, 2].CompareTo(StarList[b, 2]));

and then

(A) store the sortIndex and use it when you need to access your list rows in order, i.e. instead of StarList[x, c] use StarList[sortIndex[x], c]

(B) reorder your list using sortIndex and a well known in situ algorithm:

var temp = new double[3];
for (int i = 0; i < sortIndex.Length; i++)
{
    if (sortIndex[i] == i) continue;
    for (int c = 0; c < temp.Length; c++)
        temp[c] = StarList[i, c];
    int j = i;
    while (true)
    {
        int k = sortIndex[j];
        sortIndex[j] = j;
        if (k == i) break;
        for (int c = 0; c < temp.Length; c++)
            StarList[j, c] = StarList[k, c];
        j = k;
    }
    for (int c = 0; c < temp.Length; c++)
        StarList[j, c] = temp[c];
}

Note that after doing this, the sortIndex array is destroyed and must be discarded (i.e. don't store or use it)

Ivan Stoev
  • 159,890
  • 9
  • 211
  • 258