Quick sort (left and right pointer method)

quick sort

The principle of quick sort

Quick sort is another typical application of the idea of ​​divide and conquer in sorting algorithms. In essence, quick sort should be regarded as a recursive divide and conquer method based on bubble sort.

The name of Quick Sort is simple and rude, because as soon as you hear the name, you know the meaning of its existence, which is fast and efficient! It is one of the fastest sorting algorithms for big data.

Quicksort is a sorting algorithm developed by Tony Hall. On average, sorting n items requires O(nlogn) comparisons. In the worst case, Ο(n2) comparisons are required, but this is not common. In fact, quicksort is usually significantly faster than other Ο(nlogn) algorithms because its inner loop can be implemented efficiently on most architectures.
Please add a picture description

Suppose we need to sort an array:
insert image description here

Left and right pointer method:

Step 1:
first find a reference number in the array, which can also be called "key", usually the (first digit) or (last digit) of the array;
we first set the first digit as the reference number (key );

insert image description here
Step 2:
We need to move the selected reference number to a correct position in the array:
for example, the reference number is 3, move to a position, the left side of the position is <=3, and the right side of the position is > =3 number;
because it isleft and right pointer, is to start searching from both ends of the array, first find a number less than 3 from right to left, then find a number greater than 3 from left to right, and then exchange them. Two variables can be used here, and the names of the variables can be "left" and "right". At the beginning, you can use "left" to point to the far left, and "right" to point to the far right.
insert image description here
Note here: If you choose the leftmost data as the key, you need to go first with "right"; if you choose the rightmost data as the key, you need to go first with "left".
So "right" starts first, and walks to the left step by step (right=right -1), until it encounters a number smaller than the reference number 3, stops and points to that number, then "left" starts again, and walks to the right step by step ( left=left +1), stop until a number greater than the base number 3 is encountered.
insert image description here
Then swap the number pointed to by "left" with the number pointed to by "right".

insert image description here
This is the end of the first exchange. Next, carry out the second exchange. In the same process as above, let "right" first move to the left (right=right - 1), find a number smaller than the reference number 3, until you find 1, at this time "left" and " right" points to the same number.
insert image description here
Whenever "left" and "right" meet, swap the pointed 1 with the base number 3.
insert image description here
At this time, put the reference number back to its original position. At this time, the numbers on the left of "key" are all numbers less than 3, and the numbers on the right of "key" are all numbers greater than 3. After this, you can regard "key" as a dividing line and see two sets of arrays from this string of arrays, one group on the left side of "key", and one group on the right side of "key".

Let's deal with the set of arrays to the left of "key" first!
insert image description here

We can see that, unfortunately, a set of arrays that I input randomly does not need to be processed at this time.
But how to judge that he doesn't need to deal with it anymore?
——————
When reprocessing the array, reset the reference number 1 in the same way, "left" points to the leftmost 1, and "right" points to the left bit of the original "key", which is 2, and the left of the key The sequence and the right sequence are sorted again in this single pass, and the operation is repeated until there is only one data in the left and right sequences, or when the left and right sequences do not exist, the operation will stop.

Next, the right array of the original "key" is processed.

insert image description here
At this time, proceed with the same method as above, first find a number smaller than the reference number 6 to the left of "right", find a number greater than the reference number 6 to the right of "left", and stop.
insert image description here
Find to exchange.
insert image description here
Then "right" searches again, pointing to 4 to stop, at this time "left" and "right" point to the same number, and exchange it with "key".

insert image description here

Then use "key" as the dividing line, and process this group of arrays separately.
Follow the same method as above, and finally the array will be sorted successfully:
insert image description here
Careful students may have discovered that each round of quick sorting is actually to return the benchmark numbers of this round until all the numbers are returned. So far, sorting is over. Next, use the graphical method to show the complete process:
insert image description here
code implementation:

void quick_sort(int *arr, int begin,int end)
{
    
    
	if (end < begin )
		return;
	//left 指向最左边
	int left = begin ;
	//right  指向最右边
	int right = end ;
	int* key = &arr[begin];

	while (left != right)
	{
    
    
		while (arr[right] >= *key && right > left) 
		{
    
    
			right--;
		}
		while (arr[left] <= *key && left < right)
		{
    
    
			left++;
		}
		if (left < right)
		{
    
    
			swap(&arr[left],&arr[right]);
			
		}
		
	}
	swap(&arr[left],key);
	quick_sort(arr, begin, left-1);
	quick_sort(arr, left+1, end );
}

Overall code:

void swap(int*left,int *right)
{
    
    
	int tem = *left;
	*left = *right;
	*right = tem;
}

void quick_sort(int *arr, int begin,int end)
{
    
    
	if (end < begin )
		return;
	//left 指向最左边
	int left = begin ;
	//right  指向最右边
	int right = end ;
	int* key = &arr[begin];

	while (left != right)
	{
    
    
		while (arr[right] >= *key && right > left) 
		{
    
    
			right--;
		}
		while (arr[left] <= *key && left < right)
		{
    
    
			left++;
		}
		if (left < right)
		{
    
    
			swap(&arr[left],&arr[right]);
			
		}
		
	}
	swap(&arr[left],key);
	
	

	quick_sort(arr, begin, left-1);
	quick_sort(arr, left+1, end );
}

int main()
{
    
    
	int arr[] = {
    
     6,1,2,7,9 ,10,3,4,5,0,8 };
	int sz = sizeof arr / sizeof arr[1];

	int begin = 0;
	int end = sz-1;
	quick_sort(arr, begin,end);

	int i = 0;
	for (i = 0; i < sz; i++)
	{
    
    
		printf("%d ", arr[i]);
	}

	return 0;
}

Quicksort uses a divide and conquer strategy to divide a sequence into two subsequences.

Quick sort is another typical application of the idea of ​​divide and conquer in sorting algorithms. In essence, quick sort should be regarded as a recursive divide and conquer method based on bubble sort.

Guess you like

Origin blog.csdn.net/m0_66780695/article/details/131116712