首页 > 其他分享 >快排

快排

时间:2024-09-26 11:03:22浏览次数:5  
标签:right nums int 快排 pivot include left

快排

  • 快速排序的最优情况是每一次取到的元素都刚好平分整个数组,T(n) = 2 * T(n/2) + O(n),由 master 公式得到算法的时间复杂度为 O(nlogn),空间复杂度为 O(logn)
  • 最坏情况是数组本身有序,每一次取到的元素都是待排序列中的最值,效果相当于冒泡排序。这种情况下,算法的时间复杂度是 O(n^2),空间复杂度为 O(n)

经典快排

  • 确定性的快排在选取主元的时候,每次都选取最左边的元素。当序列为有序时,会发现划分出来的两个子序列一个里面没有元素,而另一个则只比原来少一个元素。为了避免这种情况,引入随机化来破坏这种有序状态。
#include <vector>

using namespace std;

class Solution {
public:
    void quickSort(vector<int> &array, int left, int right) {
        if (left >= right) return;
        int i = left;
        int j = right;
        int pivot = array[left];

        while (i < j) {
            while (i < j && pivot <= array[j]) {
                j--;
            }
            if (i < j) {
                array[i] = array[j];
                i++;
            }
            while (i < j && pivot >= array[i]) {
                i++;
            }
            if (i < j) {
                array[j] = array[i];
                j--;
            }
        }
        array[i] = pivot;
        quickSort(array, left, i - 1);
        quickSort(array, i + 1, right);
    }

    vector<int> sortArray(vector<int> &nums) {
        quickSort(nums, 0, nums.size() - 1);
        return nums;
    }
};

随机快排

  • 在随机化的快排里面,随机选取待排序列中的一个元素作为主元,然后再进行划分,就可以降低选到最值的概率。
#include <vector>
#include <cstdlib>
#include <ctime>

using namespace std;

class Solution {
public:
    void quickSort(vector<int> &nums, int left, int right) {
        if (left >= right) return;
        int i = left;
        int j = right;

        // 随机选个位置和第一个位置交换一下
        srand(time(nullptr));
        int pick = left + (rand() % (right - left + 1));
        swap(nums[left], nums[pick]);
        int pivot = nums[left];

        while (i < j) {
            while (i < j && nums[j] >= pivot) j--;
            if (i < j) nums[i++] = nums[j];
            while (i < j && nums[i] <= pivot) i++;
            if (i < j) nums[j--] = nums[i];
        }
        nums[i] = pivot;
        quickSort(nums, left, i - 1);
        quickSort(nums, i + 1, right);
    }

    vector<int> sortArray(vector<int> &nums) {
        quickSort(nums, 0, nums.size() - 1);
        return nums;
    }
};

荷兰国旗问题

  • 也是由大佬 Edsger Dijkstra 提出的

75. 颜色分类

#include <vector>
#include <cstdlib>
#include <ctime>

using namespace std;

class Solution {
public:
    void sortColors(vector<int> &nums) {
        // 下个放 0 的位置
        int left = 0;
        // 下个放 2 的位置
        int right = nums.size() - 1;
        int index = 0;
        while (index <= right) {
            // 如果 nums[index] 是 2,就放到最右边,直到这个位置不是 2
            while (index <= right && nums[index] == 2) {
                swap(nums[index], nums[right]);
                right--;
            }
            // 如果最后是 0,就发给到左侧区域
            if (nums[index] == 0) {
                swap(nums[index], nums[left]);
                left++;
            }
            index++;
        }
    }
};

荷兰国旗版快排

  • 原版的快排只能以 pivot 为中心,小于等于 pivot 的在左侧,大于在右侧,之确保左侧最后一个是 pivot。处理过程是从两侧向中间。
  • 荷兰国旗版快排,可以将所有等于 pivot 的放到一起,处理过程是从左到右。

912. 排序数组

#include <vector>
#include <cstdlib>
#include <ctime>

using namespace std;

class Solution {
public:
    // 把所有等于 pivot 的元素都放到一起
    void quickSort(vector<int> &nums, int left, int right) {
        if (left >= right) return;

        // 随机选个位置和第一个位置交换一下
        srand(time(nullptr));
        int pick = left + (rand() % (right - left + 1));
        swap(nums[left], nums[pick]);
        int pivot = nums[left];

        // 下一个严格小于 pivot 的元素应该放的地方
        int l = left;
        // 下一个严格大于 pivot 的元素应该放的地方
        int r = right;

        int index = l;
        while (index <= r) {
            // 如果 nums[index] 大于 pivot,就放到最右边,直到这个位置不再大于 pivot
            while (index <= r && nums[index] > pivot) {
                swap(nums[index], nums[r]);
                r--;
            }
            // 此时 nums[index] 只会小于等于 pivot
            // 再把严格小于 pivot 的移到左侧
            if (nums[index] < pivot) {
                swap(nums[index], nums[l]);
                l++;
            }
            index++;
        }

        quickSort(nums, left, l - 1);
        quickSort(nums, r + 1, right);
    }

    vector<int> sortArray(vector<int> &nums) {
        quickSort(nums, 0, nums.size() - 1);
        return nums;
    }
};

标签:right,nums,int,快排,pivot,include,left
From: https://www.cnblogs.com/sprinining/p/18433037

相关文章

  • 快排
    快速排序算法详解快速排序是一种高效的排序算法,由英国计算机科学家托尼·霍尔在1960年提出。它采用分治策略来对一个数组进行排序。快速排序在平均情况下的时间复杂度为O(nlogn),并且其性能通常比其他O(nlogn)复杂度的排序算法更优,这使得它非常受欢迎。快速排序的工作原理快......
  • 【数据结构】详细介绍各种排序算法,包含希尔排序,堆排序,快排,归并,计数排序
    目录1.排序1.1概念1.2常见排序算法2.插入排序2.1直接插入排序2.1.1基本思想2.1.2代码实现2.1.3特性2.2 希尔排序(缩小增量排序)2.2.1基本思想2.2.2 单个gap组的比较2.2.3 多个gap组比较(一次预排序)2.2.4 多次预排序2.2.5 特性3.选择排序3.1直......
  • 并行编程原理与实践-MPI实现快排
    并行编程原理与实践-MPI实现快排1.VS2022配置MPI环境可参考这篇博客:http://t.csdnimg.cn/T390g2.具体代码#include<mpi.h>#include<stdio.h>#include<stdlib.h>voidquicksort(int*array,intlow,inthigh);intpartition(int*array,intlow,inthigh);......
  • leetcode215. 数组中的第K个最大元素,小根堆/快排思想
    leetcode215.数组中的第K个最大元素给定整数数组nums和整数k,请返回数组中第k个最大的元素。请注意,你需要找的是数组排序后的第k个最大的元素,而不是第k个不同的元素。你必须设计并实现时间复杂度为O(n)的算法解决此问题。示例1:输入:[3,2,1,5,6,4],k=2......
  • 快排CMS1.2文件上传漏洞
    侵权声明本文章中的所有内容(包括但不限于文字、图像和其他媒体)仅供教育和参考目的。如果在本文章中使用了任何受版权保护的材料,我们满怀敬意地承认该内容的版权归原作者所有。如果您是版权持有人,并且认为您的作品被侵犯,请通过以下方式与我们联系:[[email protected]]。我们将在确......
  • Java 经典排序算法代码 + 注释分析(冒泡、选择、插入、希尔、快排、计数、堆排、归并)
    Java经典排序算法代码+注释分析(冒泡、选择、插入、希尔、快排、计数、堆排、归并)以下是八种经典排序算法的代码,Java8亲测可用,可以直接运行importjava.util.Arrays;publicclassSort{privatestaticfinalint[]nums={3,44,38,5,47,15,36,26,27......
  • 比快排还快(参与者:陈卓)
    有这样一种排序问题:任意给定k个(k<10w)不重复的数字,每个数字的取值范围为[1,10w]。希望设计出一种排序算法对这10万个数字进行排序,时间复杂度尽可能小。第一时间我们可能会想使用快速排序,因为快排的时间复杂度只有O(nlogn)。但有没有比O(nlogn)更快的排序方法呢?你可能会有疑问:O(nl......
  • 二分#背包#快排#LCS详解
    二分#背包#快排#LCS详解文章目录二分#背包#快排#LCS详解1.二分搜索2.01背包问题3.快速排序4.最长公共子序列1.二分搜索在处理大规模数据集时,查找操作的效率显得尤为重要。二分搜索是一种在有序数组中查找目标值的高效算法,其时间复杂度为O(logn)。二分搜索通......
  • 优雅的快排之分治与递归思想,透彻理解快排
    摘要:给你一个数组,要求你对其按照从小到大的顺序进行排序.你是怎么做的呢?英国计算机科学家东尼.霍尔在英国国家物理实验室工作的时候提出一种名为快速排序的排序算法,它可以高效地将一个数组进行快速排序.那么霍尔是怎么想到的?接下来根据从y总那里学到的以及个人的理解来介......
  • 每天写两道(四)最大子数组和、手撕快排
    53.最大子数组和.-力扣(LeetCode)给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。子数组是数组中的一个连续部分。示例1:输入:nums=[-2,1,-3,4,-1,2,1,-5,4]输出:6解释:连续子数组 [4,-1,2,1]的和最大,为 6。......