Simple and unpretentious, graphic quick-sort, multi-language implementation. (PS: there is also treasure information)

I. Introduction

Quicksort is a commutative sort , which was proposed by CAR Hoare in 1962.

2. Algorithmic thinking

The basic idea of ​​quick sort is to divide the data to be sorted into two independent parts through one-way sorting: the left side of the split point is smaller than it, and the right side is larger than it.

Then, the two parts of data are quickly sorted by this method, and the entire sorting process can be performed recursively, so that the entire data becomes an ordered sequence.

Schematic diagram of dynamic effect:

Sort (4): Quick Sort

Detailed diagrams are often more descriptive than a lot of text, so go directly to the picture:

Sort (4): Quick Sort

The above figure demonstrates the process of quick sort:

The initial state is an unordered array: 2, 4, 5, 1, 3.

After the above operation steps, the first sorting is completed , and a new array is obtained: 1, 2, 5, 4, 3.

In the new array, with 2 as the dividing point, the left side are all numbers smaller than 2, and the right side are all numbers larger than 2.

Since 2 has already found a suitable position in the array, there is no need to move it.

The array to the left of 2 has only one element, 1, so obviously there is no need to sort and the position is determined. (Note: In this case, the left pointer and the right pointer are obviously coincident. Therefore, in the code, we can set the judgment condition that the left must be smaller than the right . If it is not satisfied, there is no need to sort ).

For the arrays 5, 4, and 3 to the right of 2, set the left to point to 5 and the right to point to 3, and start to repeat the first, second, third, and fourth steps in the figure to sort the new array.

1. Code

C++:

#include <iostream>
#include <vector>

using namespace std;

int division(vector<int> &list, int left, int right){
	// 以最左边的数(left)为基准
	int base = list[left];
	while (left < right) {
		// 从序列右端开始,向左遍历,直到找到小于base的数
		while (left < right && list[right] >= base)
			right--;
		// 找到了比base小的元素,将这个元素放到最左边的位置
		list[left] = list[right];

		// 从序列左端开始,向右遍历,直到找到大于base的数
		while (left < right && list[left] <= base)
			left++;
		// 找到了比base大的元素,将这个元素放到最右边的位置
		list[right] = list[left];
	}

	// 最后将base放到left位置。此时,left位置的左侧数值应该都比left小;
	// 而left位置的右侧数值应该都比left大。
	list[left] = base;
	return left;
}

// 快速排序
void QuickSort(vector<int> &list, int left, int right){
	// 左下标一定小于右下标,否则就越界了
	if (left < right) {
		// 对数组进行分割,取出下次分割的基准标号
		int base = division(list, left, right);

		// 对“基准标号“左侧的一组数值进行递归的切割,以至于将这些数值完整的排序
		QuickSort(list, left, base - 1);

		// 对“基准标号“右侧的一组数值进行递归的切割,以至于将这些数值完整的排序
		QuickSort(list, base + 1, right);
	}
}

void main(){
	int arr[] = { 6, 4, 8, 9, 2, 3, 1 };
	vector<int> test(arr, arr + sizeof(arr) / sizeof(arr[0]));
	cout << "排序前" << endl;
	for (int i = 0; i < test.size(); i++){
		cout << test[i] << " ";
	}
	cout << endl;
	vector<int> result = test;
	QuickSort(result, 0, result.size() - 1);
	cout << "排序后" << endl;
	for (int i = 0; i < result.size(); i++){
		cout << result[i] << " ";
	}
	cout << endl;
	system("pause");
}

operation result:

Sort (4): Quick Sort

Python:

# -*- coding:utf-8 -*-

def QuickSort(input_list, left, right):
	'''
	函数说明:快速排序(升序)
	Author:
		www.cuijiahua.com
	Parameters:
		input_list - 待排序列表
	Returns:
	'''	
	def division(input_list, left, right):
		'''
		函数说明:根据left和right进行一次扫描,重新找到基准数
		Author:
			www.cuijiahua.com
		Parameters:
			input_list - 待排序列表
			left - 左指针位置
			right - 右指针位置
		Returns:
			left - 新的基准数位置
		'''	
		base = input_list[left]
		while left < right:
			while left < right and input_list[right] >= base:
				right -= 1
			input_list[left] = input_list[right]
			while left < right and input_list[left] <= base:
				left += 1
			input_list[right] = input_list[left]
		input_list[left] = base
		return left

	if left < right:
		base_index = division(input_list, left, right)
		QuickSort(input_list, left, base_index - 1)
		QuickSort(input_list, base_index + 1, right)

if __name__ == '__main__':
	input_list = [6, 4, 8, 9, 2, 3, 1]
	print('排序前:', input_list)
	QuickSort(input_list, 0, len(input_list) - 1)
	print('排序后:', input_list)

The running result is the same as above.

3. Algorithm Analysis

1. The performance of the quick sort algorithm

Sort (4): Quick Sort

2. Time complexity

When the data is ordered, it is divided into two subsequences based on the first keyword, and the former subsequence is empty, and the execution efficiency is the worst at this time.

When the data is randomly distributed, it is divided into two subsequences based on the first keyword, and the number of elements of the two subsequences is nearly equal, and the execution efficiency is the best at this time.

Therefore, the more randomly distributed the data, the better the quick sort performance; the closer the data is to the order, the worse the quick sort performance.

3. Time complexity

Quick sort requires 1 space to store the reference value during each split. And quick sort probably requires logN division processing, so the space occupied is also logN.

4. Algorithm stability

In quicksort, equal elements may swap order due to partitions, so it is an unstable algorithm.

Finally, I will give you a copy to help me get the data structure of BAT and other first-tier manufacturers. It was written by a Google master, and it is very useful for students who have weak algorithms or need to improve:

Google and Ali's Leetcode brushing notes

As well as the BAT algorithm engineer learning route, books + videos, complete learning route and instructions that I have compiled, it will definitely help those who want to become algorithm engineers (extraction code: jack):

How I became an algorithm engineer, super detailed learning path

More exciting, please see here:

Quietly jointing, stunning everyone~

Guess you like

Origin blog.csdn.net/c406495762/article/details/117740021