zoukankan      html  css  js  c++  java
  • 快速排序

    快速排序 正如它的名字一样,是一种效率较高的排序方法,面试中也经常出现,正常情况下时间复杂度为 O(n * logn)。但是快排是一种不稳定排序算法,排序过程中会打乱元素顺序。

    快排的核心是partition算法,partition算法步骤:

    1. 选取一个元素作为pivot。
    2. 将小于pivot的元素放在其左边,大于pivot的元素放在其右边
    3. 分别对pivot的左右子序列进行递归进行1,2,3

    所以partition效率高的快排效率自然高,在此介绍两种partition方法:

    partition 1

    选定一个基准之后,在数组首尾分别设置一个指针,使得小于基准的都在左边,大于基准的都在右边。

    两种不同的写法,相同的效果:

    int partition1(vector<int>& arr, int begin, int end) {
        int pivot = arr[begin];
        int l = begin, r = end + 1;
        while (l < r)
        {
            while (arr[--r] >= pivot && l < r);
            while (arr[++l] <= pivot && l < r);
            if (l >= r)break;
            swap(arr[l], arr[r]);
        }
        // 这里一定要注意,有时候l != r,所以swap(arr[begin], arr[r])和swap(arr[begin], arr[l]) 是不同的。
        swap(arr[begin], arr[r]); 
        return r;
    }
    
    int partition1(vector<int>& arr, int low, int high)
    {
        int pivot = arr[low];//选第一个元素作为枢纽元
        while (low < high)
        {
            while (low < high && arr[high] >= pivot)high--;
            arr[low] = arr[high];//从后面开始找到第一个小于pivot的元素,放到low位置
            while (low < high && arr[low] <= pivot)low++;
            arr[high] = arr[low];//从前面开始找到第一个大于pivot的元素,放到high位置
        }
        arr[low] = pivot;//最后枢纽元放到low的位置
        return high;
    }

    partition 2

    类似于冒泡排序的思想,小于基准的下沉,大于基准的上浮:

    int partition2(vector<int>& nums, int i, int j)
    {
        int pivot = nums[i];
        int location = i;
        for (int low = i + 1; low <= j; ++low)
        {
            if (nums[low] < pivot) {
                swap(nums[++location], nums[low]);
            }
        }
        swap(nums[location], nums[i]);
        return location;
    }

    快速排序

    void quickSort(vector<int>& arr, int begin, int end) {
        if (begin < end) {
            int p = partition_my(arr, begin, end);
            // int p = partition2(arr, begin, end);
            quickSort(arr, begin, p - 1);
            quickSort(arr, p + 1, end);
        }
    }
    int main()
    {
        vector<int> test{3,2,3,1,2,4,5,5,6};
        quickSort(test, 0, test.size() - 1);
        for (auto t : test) {
            cout << t << " " << endl;
        }
    }

    利用快排的partition思想解决问题:

    leetCode链接:https://leetcode.com/problems/kth-largest-element-in-an-array/submissions/

    代码:

    class Solution {
    public:
        int findKthLargest(vector<int>& nums, int k) {
            k = nums.size() - k;
            int left = 0, right = nums.size() - 1;
            while(left < right)
            {
                int p = partition_my(nums, left, right);
                if (p == k)break;
                if (p > k){
                    right = p - 1;
                }
                if (p < k){
                    left = p + 1;
                }
            }
            return nums[k];
        }
     
    int partition_my(vector<int>& arr, int begin, int end) {
        int pivot = arr[begin];
        int l = begin, r = end + 1;
        while (l < r)
        {
            while (arr[--r] >= pivot && l < r);
            while (arr[++l] <= pivot && l < r);
            if (l >= r)break;
            swap(arr[l], arr[r]);
        }
        // 这里一定要注意,有时候l != r,所以swap(arr[begin], arr[r])和swap(arr[begin], arr[l]) 是不同的。
        swap(arr[begin], arr[r]); 
        return r;
    }
        
        
    int partition1(vector<int>&arr, int low, int high)
    {
        int pivot = arr[low];//选第一个元素作为枢纽元
        while(low < high)
        {
            while(low < high && arr[high] >= pivot)high--;
            arr[low] = arr[high];//从后面开始找到第一个小于pivot的元素,放到low位置
            while(low < high && arr[low] <= pivot)low++;
            arr[high] = arr[low];//从前面开始找到第一个大于pivot的元素,放到high位置
        }
        arr[low] = pivot;//最后枢纽元放到low的位置
        return high;
    }
        
    int partition2(vector<int>& nums, int i, int j)
    {   
        int pivot = nums[i];
        int location = i ;
        for (int low = i + 1; low <= j; ++low)
        {
            if(nums[low] < pivot){
                swap(nums[++location], nums[low]);
            }
        }
        swap(nums[location], nums[i]);
        return location;
    }
    };
  • 相关阅读:
    element ui源码解析 -- button篇
    如何在vue项目中使用百度编辑器ueditor
    基于element ui的图片预览插件
    jquery weui日期选择控件添加取消按钮
    swiper如何实现轮播嵌套轮播
    jQuery weui Select组件显示指定值
    vue打包静态资源路径不正确的解决办法
    CSS垂直居中的实现
    vue学习笔记二:v-if和v-show的区别
    vue学习笔记一:用Key管理可复用元素
  • 原文地址:https://www.cnblogs.com/qiang-wei/p/12295005.html
Copyright © 2011-2022 走看看