Talking about Quick Sort--From Tricolor Flag Problem to

First of all, let's understand the time complexity and stability analysis of quick sorting.

The average time complexity of quick sorting is o(n*logn), the best case is o(n*logn), and the worst case is o(n^2)

unstable

Then let's officially start analyzing quicksort

First of all, if we want to understand quick sorting, we must first understand the tricolor flag problem:

There are many flags of white, red, and blue hanging on a rope, and the arrangement of these flags is disorderly. Now the flags on the rope should be classified and arranged according to the three colors of blue, white, and red, but the flags can only be moved on the rope, and only two flags can be exchanged at a time. Ask how to use the least number of steps to complete the arrangement of the tricolor flag?

For this kind of problem, we can put 0 for blue, 1 for white, and 2 for red, and put them in the array for sorting. We can use double pointers to put all the blue on the left of white, and all the red on the right of white. Next, look at the solution code for the tricolor flag problem

class Solution {
public:
    void sortColors(vector<int>& nums) {
        int left = 0-1,right = nums.size(),i = 0;//将left和right这么定义是为了下面快排处理边界值问题
        while(i<right)
        {
            if(nums[i]>1)
            {swap(nums[i],nums[--right]);//因为不能保证换过来的不是2所以此时i不能++
            }
            else if(nums[i]<1)
            {
            swap(nums[i++],nums[++left]);
            }
            else if(nums[i]==1){
                i++;
            }
        }
        
    }
};

This code is the passing code of RIKO 75. Color Classification

It can be seen that the idea of ​​the tricolor flag is to determine a reference value, and then exchange the value smaller than the reference value to the left of the reference value, and exchange the value greater than the reference value to the right of the reference value

 

Next, let's look at the code of quick sort with the idea of ​​tricolor flag

#include <iostream>
#include <vector>
using namespace std;
pair<int, int>Quick(vector<int>&nums,int L,int R)//将排序好的左右边界返回
{
	int temp = nums[L];
	int i = L - 1, j = R + 1,index = L;
	while (index < j)
	{
		if(nums[index]>temp)
		{
			swap(nums[index], nums[--j]);
		}
		else if (nums[index] < temp)
		{
			swap(nums[index++], nums[++i]);
		}
		else if(nums[index] == temp)
		{
			index++;
		}
	}
	return make_pair(i, j);
}
void Quick_sort(vector<int>&nums,int L,int R)
{
	if(L>=R)return;

	pair<int,int>a = Quick(nums, L, R);
    //递归利用pair返回的左右边界,再将左右边界的子数组进行排序
	Quick_sort(nums, L, a.first);
	Quick_sort(nums, a.second, R);
}
void main()
{
	vector<int>nums = { 5,6,4,3,2 };
	Quick_sort(nums, 0, nums.size() - 1);
	for (int it : nums)
	{
		cout << it << " ";
	}
}

Next, let's take the array of 56432 as an example

 We determine that the current sorting benchmark value is 5, and the values ​​of i and j are initially on both sides of the array. Currently, nums[index]=temp executes index++;

 At this time nums[index]=6>temp, we exchange 6 to the right of the array;

 Next, look at the size 1 of the exchanged number, and find that <temp at this time, we exchange this number to the left;

 4 is also swapped to the left

 3 also swaps to the left

 At this point, the sorting is over. We found that the final sorting result of the current array is 24356, and the final result is 23456. Although the order of the entire array is wrong, we found that the relative position of 5 is correct. Next, we only need to use recursion to put 5 The left and right sub-arrays are sorted, and finally a correct order can be obtained.

Guess you like

Origin blog.csdn.net/asdasd121312dasd/article/details/127783193