雪ノ下雪之下的雪

快速排序和快速选择

RY·2022-11-23 20:56·78 次阅读

快速排序和快速选择

快速排序#

核心思路#

通过分治和递归不断选择分界点,通过交换元素使分界点左边的元素小于分界点,右边的元素大于分界点。

实现方法#

复制代码
var sortArray = function(nums) {
    const quickSort = (left, right) => {
        if(left >= right) {
            return;
        }

        let i = left - 1, j = right + 1, x = nums[(i + j) >> 1];
        while(i < j) {
            do i++;
            while(nums[i] < x);
            do j--;
            while(nums[j] > x);
            if(i < j) {
                [nums[i], nums[j]] = [nums[j], nums[i]]
            }
        }
        quickSort(left, j);
        quickSort(j + 1, right);
    }
    quickSort(0, nums.length - 1);
    return nums;
};
复制代码

求topK(快速选择)#

只选择一侧区间递归,若在左侧区间,则是左侧区间的第k小个数,若在右侧区间,则是右侧区间的第k-sl小的数,sl为此时左侧区间的长度。

复制代码
var findKthLargest = function(nums, k) {
    let resIndex = k;
    let quickSort = (left, right) => {
        if(left >= right) {
            return;
        }

        let i = left - 1, j = right + 1,  x = nums[(i + j) >> 1];
        while(i < j) {
            do i++;
            while(nums[i] > x);
            do j--;
            while(nums[j] < x);
            if(i < j) {
                [nums[i], nums[j]] = [nums[j], nums[i]];
            }
        }
        if(j - left + 1 >= k) quickSort(left, j);
        else {
            k = k - j + left - 1;
            quickSort(j + 1, right);
        }
    }
    quickSort(0, nums.length - 1);
    return nums[resIndex - 1];
};
复制代码

这里需要不断改变k的值的原因是,i 和 j 的取值是由left和right决定的,而left和right又是不断变化的,原始k的值是根据 0 和 nums.length决定,所以需要在排序过程中不断的改变。

其次,把k看作一个数量,即nums中最小的前k个数。如果sl = j - left + 1这个范围内是nums中最小的 sl 个数,如果 k 大于 sl,则后续只排右半部分。这时则不需要看前k个最小的数了,把前面的一部分删除,需要看 sr = right - j + 1 中前 k - j + left - 1小的数了。

posted @   雪之下。  阅读(78)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
点击右上角即可分享
微信分享提示
目录