回顾排序算法 快速排序及其应用

快排和求第k大数值

快排原理

在这里插入图片描述
为什么快排的复杂度有 logn,是因为他每次都是两个相互交换,所以是以2为底数。

第k大数值: 确定k的落值范围,来判断是否需要排序。

package com.company;

import java.util.Arrays;

public class Main {

    public static void main(String[] args) {

        int[] arr = {2, 3, 4, 5, 1};
        quickSort(arr, 0, arr.length - 1);
        System.out.println(Arrays.toString(arr));

        int[] arr2 = {2, 3, 4, 5, 1};
        int resultIndex1 = kMaxNum(arr, 5);
        System.out.println("result is " + arr[resultIndex1]);

        int[] arr3 = {2, 3, 4, 5, 1};
        int resultIndex2 = kMaxNum(arr, 1);
        System.out.println("result is " + arr[resultIndex2]);
    }

    public static int kMaxNum(int[] arr, int k) {

        if (k > arr.length) {
            throw new IllegalArgumentException("不合法的k值");
        }

        return quickSortForKMaxNum(arr, 0, arr.length - 1, k - 1);
    }


    /**
     * 求第K大值,首先判断K的落值范围。
     *  @param arr
     * @param l
     * @param r
     * @return
     */
    public static int quickSortForKMaxNum(int[] arr, int l, int r, int k) {
        if (l > r) {
            return l;
        }

        int i = l;
        int j = r;
        int temp = arr[i];

        // 循环找到一个大的,一个小的,然后相互交换
        while (i < j) {
            // 从右往左找到一个第一个小于基准值的
            while (i < j && arr[j] > temp) {
                j--;
            }
            arr[i] = arr[j];

            // 从左往右找到一个大于基准值的
            while (i < j && arr[i] <= temp) {
                i++;
            }

            arr[j] = arr[i];
        }
        // 最后找到没有填的值
        arr[i] = temp;
        if (i == k) {
            return i;
        }
        if (inRange(l, i - 1, k)) {
            return quickSortForKMaxNum(arr, l, i - 1, k);
        }
        else if (inRange(i + 1, r, k)) {
            return quickSortForKMaxNum(arr, i + 1, r, k);
        }
        return l;
    }

    public static boolean inRange(int min, int max, int value) {
        return min <= value && max >= value;
    }

    public static void quickSort(int[] arr, int l, int r) {
        if (l >= r) {
            return;
        }

        int i = l;
        int j = r;
        int temp = arr[i];

        // 循环找到一个大的,一个小的,然后和基准值交换
        while (i < j) {
            // 从右往左找到一个第一个小于基准值的
            while (i < j && arr[j] > temp) {
                j--;
            }
            arr[i] = arr[j];

            // 从右向左找到最小的值
            while (i < j && arr[i] <= temp) {
                i++;
            }

            arr[j] = arr[i];
        }

        arr[i] = temp;

        quickSort(arr, l, i - 1);
        quickSort(arr, i + 1, r);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值