以下mergesort来自数据结构和算法分析(Weiss)。我想知道的是合并步骤中的最后一个for
循环。我知道我们必须将tmpArray
复制回array
,但我不明白为什么我们从rightend
执行此操作,以及为什么我们没有i
去从0
到tmpArray.size
。有人可以解释一下吗?
public static void mergeSort( Comparable [ ] a )
{
Comparable [ ] tmpArray = new Comparable[ a.length ];
mergesort( a, tmpArray, 0, a.length - 1 );
}
public static void mergesort( Comparable [ ] a, Comparable [ ] tmpArray,
int left, int right )
{
if( left < right ) {
int center = ( left + right ) / 2;
mergesort( a, tmpArray, left, center );
mergesort( a, tmpArray, center + 1, right );
merge( a, tmpArray, left, center + 1, right );
}
}
public static void merge( Comparable [ ] a, Comparable [ ] tmpArray,
int leftPos, int rightPos, int rightEnd )
{
int leftEnd = rightPos - 1;
int tmpPos = leftPos;
int numElements = rightEnd - leftPos + 1;
while( leftPos <= leftEnd && rightPos <= rightEnd )
if( a[ leftPos ].compareTo( a[ rightPos ] ) <= 0 )
tmpArray[ tmpPos++ ] = a[ leftPos++ ];
else
tmpArray[ tmpPos++ ] = a[ rightPos++ ];
while( leftPos <= leftEnd ) // Copy rest of first half
tmpArray[ tmpPos++ ] = a[ leftPos++ ];
while( rightPos <= rightEnd ) // Copy rest of right half
tmpArray[ tmpPos++ ] = a[ rightPos++ ];
for( int i = 0; i < numElements; i++, rightEnd-- )
a[ rightEnd ] = tmpArray[ rightEnd ]; // Copy tmpArray back
}
答案 0 :(得分:1)
我认为以这种方式做事的主要原因是因为内部循环破坏性地修改了rightPos
(子阵列开始的位置)的值(注意使用rightPos++
。因此,为了正确地写回值,最后一个循环向后计数到rightPos
最初的位置。如果它只是从rightPos
开始并向前计数,那么它将写入错误的索引
那就是说,我认为没有任何理由这样做。只是声明新变量并修改这些值而不是破坏输入并进行额外的体操来恢复原始值会更容易。
希望这有帮助!