繁体   English   中英

如何计算合并排序中的比较次数?

[英]How to calculate number of comparisons in merge sort?

这是我的算法。 我曾尝试将numComparesnumMoves放置在许多不同的位置,但无法在可以看到有效结果的地方找到它。 比较= 2个整数正在彼此移动求值=一个元素已从其位置移出。 因此,交换将是2步。

 /**
   * Internal method that merges two sorted halves of a subarray.
   * @param a an array of Comparable items.
   * @param tmpArray an array to place the merged result.
   * @param leftPos the left-most index of the subarray.
   * @param rightPos the index of the start of the second half.
   * @param rightEnd the right-most index of the subarray.
   */
  private static void merge( int[] a, int[ ] tmpArray, int leftPos, int rightPos, int rightEnd )
  {
      int leftEnd = rightPos - 1; //left's last position
      int tmpPos = leftPos; //left-most
      int numElements = rightEnd - leftPos + 1;

      // Main loop
      while( leftPos <= leftEnd && rightPos <= rightEnd ){ //left and right pointers don't meet limit
        //numCompares = numCompares+1; //+2 because of 2 conditions
          if(a[leftPos] <= a[rightPos]){ //if left half element <= right half element
              tmpArray[ tmpPos++ ] = a[ leftPos++ ]; //copy left side elements
            }else{
              tmpArray[ tmpPos++ ] = a[ rightPos++ ]; //copy right side elements
        }
        numMoves++;
        numCompares = numCompares+2;
      }
      while( leftPos <= leftEnd ){    // Copy rest of first half while left is <= left end
          tmpArray[ tmpPos++ ] = a[ leftPos++ ];
          numCompares++;
          numMoves++;
      }
      while( rightPos <= rightEnd ){  // Copy rest of right half while right is < right-most
          tmpArray[ tmpPos++ ] = a[ rightPos++ ];
          numCompares++;
          numMoves++;
      }
      // Copy tmpArray back
      for( int i = 0; i < numElements; i++, rightEnd-- ){
          a[ rightEnd ] = tmpArray[ rightEnd ];
      }
  }

鉴于您想要最大的精度,这将是我的方法:

/**
     * Internal method that merges two sorted halves of a subarray.
     * @param a an array of Comparable items.
     * @param tmpArray an array to place the merged result.
     * @param leftPos the left-most index of the subarray.
     * @param rightPos the index of the start of the second half.
     * @param rightEnd the right-most index of the subarray.
     */
    private static void merge( int[] a, int[ ] tmpArray, int leftPos, int rightPos, int rightEnd )
    {
        int leftEnd = rightPos - 1;
        int tmpPos = leftPos;
        int numElements = rightEnd - leftPos + 1;

        while( leftPos <= leftEnd){
            numCompares++; // this is for leftPos <= leftEnd
            if(rightPos <= rightEnd) {
                numCompares++; // this is for rightPos <= rightEnd
                if (a[leftPos] <= a[rightPos]) { //if left half element <= right half element
                    tmpArray[tmpPos++] = a[leftPos++]; //copy left side elements
                } else {
                    tmpArray[tmpPos++] = a[rightPos++]; //copy right side elements
                }
                numMoves++;
                numCompares++; // this is for a[leftPos] <= a[rightPos]
            } else {
                break;
            }
        }
        numCompares++; //The while loop exited. This has happened because (leftPos <= leftEnd) or (rightPos <= rightEnd) failed.


        while( leftPos <= leftEnd ){    // Copy rest of first half while left is <= left end
            tmpArray[ tmpPos++ ] = a[ leftPos++ ];
            numCompares++;
            numMoves++;
        }
        numCompares++; //The while loop exited. This has happened because leftPos <= leftEnd failed.

        while( rightPos <= rightEnd ){  // Copy rest of right half while right is < right-most
            tmpArray[ tmpPos++ ] = a[ rightPos++ ];
            numCompares++;
            numMoves++;
        }
        numCompares++; //The while loop exited. This has happened because rightPos <= rightEnd failed.


        // Copy tmpArray back
        // I assume that you don't want account for this operation in your measurements, since you didn't try to do it yourself?
        for( int i = 0; i < numElements; i++, rightEnd-- ){
            a[ rightEnd ] = tmpArray[ rightEnd ];
            // numCompares++; // This is for (i < numElements)
            // numMoves++;
        }
        // numCompares++; //The for loop exited. This has happened because (i < numElements) failed.
    }

如果将其与渐近运行时间进行比较,请尝试逐渐增加大小并绘制测量图。 它不太适合小样本量。 另外,此代码还计算了数组中的写入量。 如果您也要考虑读取,则需要在numMoves递增的地方添加两个而不是一个。

希望能帮助到你。 祝好运 :)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM