快速排序

243 阅读1分钟

方便使用

public void sort(int[] a) {
    qsort(a, 0, a.length - 1);
}

快速排序的递归写法

public void qsort(int[] a, int left, int right) {
    if (left < right) {
        int mid = partition(a, left, right);
        qsort(a, left, mid - 1);
        qsort(a, mid + 1, right);
    }
}

非递归写法

public void qsort(int[] a, int left, int right) {
    LinkedList<Range> stack = new LinkedList<>();
    stack.push(new Range(left, right));
    while (!stack.isEmpty()) {
        Range range = stack.pop();
        int mid = partition(a, range.left, range.right);
        stack.push(new Range(mid + 1, right));
        stack.push(new Range(left, mid - 1));
    }
}
public class Range {
    int left;
    int right;
    Range(){}
    Range(int left, int right){
        this.left = left;
        this.right = right;
    }
}

快速排序的ForkJoin写法

ForkJoinPool forkJoinPool = new ForkJoinPool();

public void qsort(int[] a, int left, int right) {
    if (left < right) {
        int mid = partition(a, left, right);
        forkJoinPool.execute(()->{
            qsort(a, left, mid - 1);
        });
        forkJoinPool.execute(()->{
            qsort(a, mid + 1, right);
        });
    }
}

划分,从右边找到一个比pivot小的,从左边找到一个比pivot大的,两者交换,然后继续,直到两者相遇,把pivot赋值给那个相遇点,并把相遇点坐标返回。

public int partition(int[] a, int left, int right) {
    int pivot = a[left];
    int i = left, j = right;
    while (i < j) {
        while (i < j && a[j] >= pivot) {
            j--;
        }
        while (i < j && a[i] <= pivot) {
            i++;
        }
        if (i != j) {
            int temp = a[i];
            a[i] = a[j];
            a[j] = temp;
        }
    }
    a[i] = pivot;
    return i;
}

划分,从右边找到一个比pivot小的,放到左边,从左边找到一个比pivot大的,放到右边,直到前后相遇,把pivot赋值给那个相遇点,并把相遇点坐标返回。

public int partition(int[] a, int left, int right) {
    int pivot = a[left];
    int i = left, j = right;
    while (i < j) {
        while (i < j && a[j] >= pivot) {
            j--;
        }
        a[i++] = a[j];
        while (i < j && a[i] <= pivot) {
            i++;
        }
        a[j--] = a[i];
    }
    a[i] = pivot;
    return i;
}

在数组中查找第n大的值 (递归)

public int findNthBiggerNumber(int[] a, int left, int right, int n) {
    if (left <= right) {
        int mid = partition(a, left, right);
        if (mid < a.length - n) {
            return findNthBiggerNumber(a, mid + 1, right, n);
        }
        if (mid > a.length - n) {
            return findNthBiggerNumber(a, left, mid - 1, n);
        }
        return a[mid];
    }
    return 0;
}

在数组中查找第n大的值 (非递归)

public int findNthBiggerNumber(int[] a, int left, int right, int n) {
    LinkedList<Range> stack = new LinkedList<>();
    stack.push(new Range(left, right));
    while (!stack.isEmpty()) {
        Range range = stack.pop();
        int mid = partition(a, range.left, range.right);
        if (mid < a.length - n) {
            stack.push(new Range(mid + 1, right));
        }
        if (mid > a.length - n) {
            stack.push(new Range(left, mid - 1));
        }
        if (mid == a.length - n) {
            return a[mid];
        }
    }
}
public class Range {
    int left;
    int right;
    Range(){}
    Range(int left, int right){
        this.left = left;
        this.right = right;
    }
}