简体   繁体   中英

How to calculate number of comparisons in merge sort?

This is my algorithm. I've tried placing numCompares and numMoves in many different locations, but I'm not able to get it where I can see valid results. Compare = 2 integers being evaluated by one another move = an element has been moved from its position. So a swap would be 2 moves.

 /**
   * 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 ];
      }
  }

This would be my approach given that you want max precision:

/**
     * 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.
    }

If you are comparing it to the asymptotic running time, then try to increase the size gradually and graph the measurements. It's unlikely that it will fit well on small sample sizes. Also as a sidenote, this code count the amount of writes in the array. If you want to account for reads too, you would need to add two instead of one everywhere numMoves is incremented.

Hope it helps. Good luck :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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