Mergesort:合并操作的最后一步是什么?

时间:2012-05-07 18:07:15

标签: algorithm sorting mergesort

以下mergesort来自数据结构和算法分析(Weiss)。我想知道的是合并步骤中的最后一个for循环。我知道我们必须将tmpArray复制回array,但我不明白为什么我们从rightend执行此操作,以及为什么我们没有i去从0tmpArray.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
}

1 个答案:

答案 0 :(得分:1)

我认为以这种方式做事的主要原因是因为内部循环破坏性地修改了rightPos(子阵列开始的位置)的值(注意使用rightPos++。因此,为了正确地写回值,最后一个循环向后计数到rightPos最初的位置。如果它只是从rightPos开始并向前计数,那么它将写入错误的索引

那就是说,我认为没有任何理由这样做。只是声明新变量并修改这些值而不是破坏输入并进行额外的体操来恢复原始值会更容易。

希望这有帮助!