快速排序实现与如何求解第K大问题

快速排序,这种排序方式时间复杂度平均情况下为o(nlogn),而且适合数据非常多的排序方法。它采用一种分治思想

,在执行的过程种就把第K大问题解决了。代码很简单但是非常巧妙,不用额外申请内存空间。

 

代码如下可以自己跑一下:

package com.jxd.test;

public class QuickSort {
    public static void main(String[] args) {
        int arr[] = new int[]{1, 9, 2, 4, 18, 21,21,15, 33, 16, 22, 51, 88, 53,99};
        new QuickSort().quick_sort(arr);
        System.out.println("");

    }

    public void quick_sort(int[] arr) {
        quick_sort_c(arr, 0, arr.length - 1);
    }

    private void quick_sort_c(int[] arr, int first, int end) {
        if (first >= end) return;//递归停止
        int i = partition(arr, first, end);//获取分区下标

        //这里我随便找了一个数字 你可以自己改一下,第三大的数一定出现在下标为12的位置
        if(i==12) System.out.println("第三大的数为:"+arr[i]);

        quick_sort_c(arr, i + 1, end);
        quick_sort_c(arr, first, i - 1);
    }

    /**
     * 这个方法不用额外申请内存空间
     *
     * @param arr
     * @param first
     * @param end   最后一个元素
     */
    private int partition(int[] arr, int first, int end) {
         //锚点数据我们选的最后一个,正常情况下,我们去个随机数 firt -end 之间随机取
         //让数量尽量左右均摊,还有一种方式取 第一位 ,中间位 末位 比较小 取这个中间数的下标就可以
        int temp = arr[end];//锚点数据,所有数据都要和锚点数据比较

        int i = first;//维护两个指针
        for (int j = first; j <= end; j++) {
//当i和j指针所指向的数据只要比temp小,就两个指针同步走,当发现有比当前所指向的数据
//比temp大的时候 ,i指针停下,j指针继续向前走,只要j发现比temp小的就和i交换,这样一路走下来,
就会以temp为分界点,一边比temp小一遍比temp大

            if (arr[j] < temp) {
                if(i!=j)   {
                    swap(arr, i, j);//交换一下数
                }
                i++;
            }
        }
        if (arr[i] > temp) {//数据最后和arr[i] 判断一下
            swap(arr, i, end);//交换一下数
        }
        return i;
    }

    /**
     * 数组的互换方法
     * 下标source 和target互换
     *
     * @param a
     * @param source
     * @param target
     */
    private void swap(int a[], int source, int target) {
        if (source == target) return;
        int sindex = a[source];
        int tindex = a[target];
        a[source] = tindex;
        a[target] = sindex;
    }
}

你可能感兴趣的:(算法)