Merge Sorting In Place合并排序(原地排序)

huangapple go评论75阅读模式
英文:

Merge Sorting In Place

问题

以下是您要翻译的内容:

我正在编写一个原地排序的归并排序方法,它可以对元素进行排序而无需分配额外的内存。然而,目前它还不能正常工作,我想知道是否有人可以帮助我,因为我理解这是一个相对简单的操作。提前谢谢您的帮助。

我的归并排序方法:

RegisterClass[] runMergeSort()
{
   RegisterClass[] mergeSorted = new RegisterClass[capacity];
   
   for (int counter = 0; counter < size; counter++)
   {
      mergeSorted[counter] = registerArray[counter];
   }
   
   runMergeSortHelper(mergeSorted, 0, size - 1);
   
   return mergeSorted;
}

我的辅助方法,使用递归:

private void runMergeSortHelper(RegisterClass[] workingArray,
                                int lowIndex,
                                int highIndex)
{
   int midIndex = (lowIndex + highIndex) / 2;
   
   if (lowIndex < highIndex)
   {
      
      runMergeSortHelper(workingArray, lowIndex, midIndex);
      runMergeSortHelper(workingArray, midIndex+1, highIndex);
                     
      runMerge(workingArray, lowIndex, midIndex, highIndex);
   }
}

最后,我的归并方法,应该将所有元素排序,然而实际上只能部分排序。

private void runMerge(RegisterClass[] workingArray,
                      int lowIndex,
                      int midIndex,
                      int highIndex)
{
   int counterJay = midIndex;
   int counterAye = lowIndex;
   int counterKay = lowIndex - 1;
   
   while (counterAye < midIndex && counterJay <= highIndex)
   {
      counterKay++;
      
      if (workingArray[counterAye].compareTo(workingArray[counterJay]) <= -1)
      {
         counterAye++;
      }
      
      else
      {
         swapValues(workingArray, counterAye, counterJay);
         counterJay++;
         counterAye++;
      }
   }
   
   while (counterAye < midIndex)
   {
      counterKay++;
      swapValues(workingArray, counterAye, counterKay);
      counterAye++;
   }
   
   while (counterJay <= highIndex)
   {
      counterKay++;
      swapValues(workingArray, counterJay, counterKay);
      counterJay++;
   }
}

非常感谢您提供的任何建议。我已经在网上搜索过,但似乎没有什么帮助。请不要给我提供不是原地解决方案的解决方案。

英文:

I am working on a Merge Sort method which sorts elements in-place without allocating extra memory. However, it isn't working as of now and I was wondering if anyone could help me, as I understand it is a relatively simple operation. Thank you in advance.

My merge sort method:

      RegisterClass[] runMergeSort()
  {
     RegisterClass[] mergeSorted = new RegisterClass[capacity];
     
     for (int counter = 0; counter &lt; size; counter++)
        {
           mergeSorted
0
+
网站访问量
= registerArray
0
+
网站访问量
; } runMergeSortHelper(mergeSorted, 0, size - 1); return mergeSorted; }

My helper method, which uses recursion:

      private void runMergeSortHelper(RegisterClass[] workingArray,
                                  int lowIndex,
                                  int highIndex)
  {
     int midIndex = (lowIndex + highIndex) / 2;
     
     if (lowIndex &lt; highIndex)
        {
           
           runMergeSortHelper(workingArray, lowIndex, midIndex);
           runMergeSortHelper(workingArray, midIndex+1, highIndex);
                          
           runMerge(workingArray, lowIndex, midIndex, highIndex);
        }
              

  }

And finally, my Merge method, which SHOULD be putting everything into order, however, it only does this partially.

      private void runMerge(RegisterClass[] workingArray,
                        int lowIndex,
                        int midIndex,
                        int highIndex)
  {
     int counterJay = midIndex;
     int counterAye = lowIndex;
     int counterKay = lowIndex - 1;
              
     while (counterAye &lt; midIndex &amp;&amp; counterJay &lt;= highIndex)
        {
           counterKay++;
           
           if (workingArray[counterAye].compareTo(workingArray[counterJay]) &lt;= -1)
              {
                 counterAye++;
              }
           
           else
              {
                 swapValues(workingArray, counterAye, counterJay);
                 counterJay++;
                 counterAye++;
              }
           
        }
     
     while (counterAye &lt; midIndex)
        {
           counterKay++;
           swapValues(workingArray, counterAye, counterKay);
           counterAye++;
        }
     
     while (counterJay &lt;= highIndex)
        {
           counterKay++;
           swapValues(workingArray, counterJay, counterKay);
           counterJay++;
        }
  }

Any advice at all would much be appreciated. I've looked online but nothing seems to help. Please do not refer me to a solution which is NOT an in-place solution.

答案1

得分: 1

交换在合并函数使用的逻辑中是行不通的。当发生交换时,从左侧交换到右侧的元素现在已经失去顺序,将小于(或等于)左侧所有剩余元素。

每当发现右侧的元素小于左侧的元素时,需要对数组的该部分进行右旋,将右侧元素放入正确的位置。


不用采用更复杂的实现,可以通过扫描右侧来进行一小部分优化,找到 k = 小于左侧当前元素的前导元素数量,然后进行 k 元素的右旋转。对于随机数据,这不会有太大帮助,但对于逆向排序的数据,会有相当大的帮助。

英文:

Swapping isn't going to work with the logic used by the merge function. When a swap occurs, the element that is swapped from the left side to the right side is now out of order, and will be less than (or equal to) all of the remaining elements on the left side.

Whenever an element on the right side is found to be less than an element on the left side, a right rotate of that part of the array is needed to put the right side element into place.


Without resorting to a more complicated implementation, a small optimization can be made by scanning the right side for k = number of leading elements less than the current element on the left side, then do a rotate right by k elements. For random data, this won't help much, but for reverse sorted data, it would help quite a bit.

huangapple
  • 本文由 发表于 2020年9月10日 05:58:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/63820090.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定