快排

小橋落花流水發表於2020-10-27

快排的基本思想

快排用到的是分而治之的思想,隨機的選取陣列中的一個元素pivot,將小於pivot的排在左邊,大於等於pivot的排在右邊, 然後在對左右兩邊的序列採用相同的方法,直至每個子陣列只剩一個元素為止。

    //單指標
    int randomPartion(vector<int> &nums,int left,int right){
        int rand_index=rand()%(right-left+1)+left;  //最好隨機
        swap(nums[left],nums[rand_index]);
        int pivot=nums[left];
        int j=left;
        for(int i=left+1;i<=right;i++){
            if(nums[i]<pivot){
                j++;
                swap(nums[i],nums[j]);
            }
            
        }
        swap(nums[j],nums[left]);
        return j;
    }
    //雙指標
    int randomPartion2(vector<int> &nums,int left,int right){
        int rand_index=rand()%(right-left+1)+left;  //最好隨機
        swap(nums[left],nums[rand_index]);
        int pivot=nums[left];  //left 鹹魚
        while(left<right){
            while(left<right&&nums[right]>=pivot){
                right--;
            }
            nums[left]=nums[right];  //right 鹹魚
            while(left<right&&nums[left]<pivot){
                left++;
            }
            nums[right]=nums[left];  //left 鹹魚
        }
        nums[left]=pivot;
        return left;
    }
    void quick(vector<int> &nums,int left,int right){
        if(left<right){
            int q=randomPartion(nums,left,right);
            quick(nums,left,q-1);
            quick(nums,q+1,right);
        }
    }

    //在topK中的應用
    int findKthLargest(vector<int>& nums, int k) {
        int target=nums.size()-k;
        int left=0,right=nums.size()-1;
        while(1){
            int index=randomPartion2(nums,left,right);
            if(index==target)
                return nums[target];
            else if(index<target){
                left=index+1;
            }
            else{
                right=index-1;
            }
        }
    }

快排的應用:

 

 

 

相關文章