简体   繁体   中英

I am having trouble with using Median and Mean as pivot in Quicksort

For a class project I am supposed to test Quicksort with different pivots (Low, High, Midpoint, Random, Median, and Mean), but I am having trouble getting it to work with wall of them. So far I have used two different Quicksort methods and I have been able to sort a random array with everything up to random, but not with mean or median. "Partition" work with Low, Midpoint and Random, while "Partition1" works with High.

Any help is greatly appreciated and If there is any more I should add just let me know.

Here is the code that I've used so far. "Partition1" is from GFG and "Partition" is from my textbook.

`

import java.util.Arrays;

import java.util.Random;

public class QSort {
public static int comparisonCount;
public static int swapCount;
public static void main(String[] args){

    Random r = new Random();
    int N= 10;

    int[] test = new int[N]; //random integer array
    for (int i =0; i < test.length; i++){
        test[i] = r.nextInt(N*2);
    }

    System.out.println(Arrays.toString(test));
    long startTime = System.nanoTime();
    Quicksort(test, 0, test.length-1);
    long endTime = System.nanoTime();
    long duration = (endTime - startTime);

    System.out.println(Arrays.toString(test));
    System.out.println("Number of Comparisons "+ comparisonCount);
    System.out.println("Number of swaps "+ swapCount);//1000000
    System.out.println("QuickSort Duration in millisecond is "+(duration/1000000));
    System.out.println("length is "+(test.length-1));


}


    public static double median(int[] arr){
    double median;
    if (arr.length % 2 == 0) {
        median = ((double) arr[arr.length / 2] + (double) arr[arr.length / 2 - 1]) / 2;
    }
    else {
        median = (double) arr[arr.length / 2];
    }
    return median;
}

static void swap(int[] arr, int i, int j)
{
    swapCount++;
    int temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}

public static int Partition1(int[] arr, int low, int high)
{

    int pivot =arr[high];

    int i = (low - 1);

    for(int j = low; j <= high - 1; j++)
    {

        if(largerThan(arr[j],pivot))
        {
            i++;
            swap(arr, i, j);
        }
    }
    swap(arr, i+1, high);
    return (i+1);
}

public static int mean(int[] arr){
    double total = 0;
    for(int i=0; i<arr.length; i++){
        total = total + arr[i];
    }
    double average = total / arr.length;
    return (int)average;
}

public static int Partition(int[] numbers, int low, int high) {
    int midpoint = low + (high - low)/2; // Calculate Midpoint
    //Random rand= new Random(); // for random pivot
    //int pivot = numbers[rand.nextInt(high-low)+low];
    int pivot = numbers[high];

    boolean done = false;
    while (!done) {
        while (largerThan(numbers[low], pivot)) {
            low+=1;
        }

        while (largerThan(pivot, numbers[high])) {
            high-=1;
        }

        if (low >= high) {
            done = true;
        }
        else {
            swap(numbers, low, high);

            low+=1;
            high-=1;
        }
    }

    return high;
}

public static boolean largerThan( int i, int m){
    comparisonCount++;
    return i < m;
}



public static void Quicksort(int[] numbers, int low, int high) {
    if (high <= low || low >= high) {
        return;
    }

        var Index = Partition1(numbers, low, high);

        Quicksort(numbers, low, Index-1); //Index-1 for Partion1 and just Index for Partition
        Quicksort(numbers, Index + 1, high);
    }

} `

Example C code for Lomuto Partition. It swaps middle element to last, but that can be removed. Recurse on smaller, loop on larger limits stack space complexity to O(log2(n)), but worst case time complexity remains O(n^2). You don't need uint64_t either (just use int instead).

void QuickSort(uint64_t a[], int lo, int hi)
{
    while (lo < hi){
        uint64_t t;
        uint64_t p = a[(lo+hi)/2];      /* use mid point for pivot */
        a[(lo+hi)/2]= a[hi];            /* swap with a[hi] */
        a[hi] = p;
        int i = lo;
        for (int j = lo; j < hi; ++j){  /* Lomuto partition */
            if (a[j] < p){
                t = a[i];
                a[i] = a[j];
                a[j] = t;
                ++i;
            }
        }
        t = a[i];
        a[i] = a[hi];
        a[hi] = t;
        if(i - lo <= hi - i){           /* recurse on smaller partiton, loop on larger */
            QuickSort(a, lo, i-1);
            lo = i+1;
        } else {
            QuickSort(a, i+1, hi);
            hi = i-1;
        }
    }
}

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