1

我在内存中有以下菱形数组,从基地址 5000 开始。第一个有效值位于 5008(索引 2),所有其他值都相对于它定位。

 .  .  4  .  .
 .  3  7  8  .
 2  2  9  8  5
 .  1  5  9  .
 .  .  3  .  .

所有值都表示为“。” 数组中的未初始化,因此不应访问它们。

现在的问题。我需要在 MIPS 中对这个数组进行排序,而不访问内存中未初始化的值。由于内存限制,我无法使用钻石的所有有效索引创建一个新数组。所以基本上,我被卡住了。

4

1 回答 1

3

单元格的行k可以计算为:

row(k) = k < (S+1)*(S+1)/4 ? isqrt(k) : S - 1 - isqrt((S*S-1)/2 - k)

n菱形数组中行的缩进为:

indent(n) = abs((S - 1)/2 - n)

n开始的单元格是:

start(n) = n < S/2 ? n*n : (S*S+1)/2 - (S-n)*(S-n)

结合这些,您可以计算 cell 的索引k

index(k) = row(k)*S + indent(n) + (k - start(row(k)))

例子:

S = 5
. . # . .
. # # # .
# # # # #
. # # # .
. . # . .

cell    row     indent  start   index
0       0       2       0       2
1       1       1       1       6
2       1       1       1       7
3       1       1       1       8
4       2       0       4       10
5       2       0       4       11
6       2       0       4       12
7       2       0       4       13
8       2       0       4       14
9       3       1       9       16
10      3       1       9       17
11      3       1       9       18
12      4       2       12      22

使用它,您可以轻松实现选择排序

/// Calculates the index of cell k in a diamond array of size S.
int index(int k, int S)
{
    int row = k < (S+1)*(S+1)/4 ? isqrt(k) : S - 1 - isqrt((S*S-1)/2 - k);
    int indent = abs((S - 1)/2 - row);
    int start = n < S/2 ? n*n : (S*S+1)/2 - (S-n)*(S-n);
    return row*S + indent + (k - start);
}

/// Sorts the diamond array data, of size S.
void diamondSelectionSort(int[] data, int S)
{
    int total = (S*S+1)/2;
    for (int i = 0; i < total; i++)
    {
        int indexI = index(i,S);

        int bestCell = i;
        int bestIndex = indexI;
        int bestValue = data[bestIndex];

        for (int j = i+1; j < total; j++)
        {
            int indexJ = index(j,S);

            if (data[indexJ] < bestValue)
            {
                bestCell = j;
                bestIndex = indexJ;
                bestValue = data[indexJ];
            }
        }
    }

    if (bestIndex > i)
    {
        data[bestIndex] = data[indexI];
        data[indexI] = bestValue;
    }
}

/// Integer square root. Adopted from
/// http://home.utah.edu/~nahaj/factoring/isqrt.c.html
int isqrt (int x)
{
    if (x < 1) return 0;

    int squaredbit = (int) ((((unsigned int) ~0) >> 1) & 
            ~(((unsigned int) ~0) >> 2));
    int remainder = x;
    int root = 0;
    while (squaredbit > 0) {
        if (remainder >= (squaredbit | root)) {
            remainder -= (squaredbit | root);
            root = (root >> 1) | squaredbit;
        } else {
            root >>= 1;
        }
        squaredbit >>= 2; 
    }

    return root;
}

index()可以展开一点:

/// Calculates the index of cell k in a diamond array of size S.
int index(int k, int S)
{
    int row, indent, start;
    if (k < (S+1)*(S+1)/4)
    {
        row = isqrt(k);
        indent = (S - 1)/2 - row;
        start = n*n;
    }
    else
    {
        row = S - 1 - isqrt((S*S-1)/2 - k);
        indent = row - (S - 1)/2;
        start = (S*S+1)/2 - (S-n)*(S-n);
    }
    return row*S + indent + (k - start);
}
于 2013-07-01T10:20:52.050 回答