Templates and applications of quick sort and merge sort algorithms

Templates and applications of quick sort and merge sort algorithms

1. Quick Sort

Core idea: Divide a sequence into two parts, all the numbers in the left half are less than or equal to or greater than or equal to all the numbers in the right half, recursively process the left and right parts

Specific steps: where qis an array, lis the subscript of the left endpoint of the array, and ris the subscript of the right endpoint of the array

  • Determine the cut-off pointq[(l+r)>>1] , that is,q[(l+r)/2]
  • Use double pointers to adjust the left and right intervals, so that the data in the left interval is less than or equal to the data in the right interval (ascending order), or make the data in the left interval greater than or equal to the data in the right interval (descending order)
  • Recursive processing of left and right intervals[l,j] and[j+1,r]

Algorithm example:

#include<iostream>
using namespace std;

const int N = 1e6 + 10;
int q[N];

void quick_sort(int* q, int l, int r)//快排模板
{
    
    
	if (l >= r) return;//必须 >=
	int x = q[l + r >> 1], i = l - 1, j = r + 1;
	while (i < j)
	{
    
    
		while (q[++i] < x);
		while (q[--j] > x);
		if (i < j) swap(q[i], q[j]);
	}
	quick_sort(q, l, j);
	quick_sort(q, j + 1, r);
}

int main()
{
    
    
	int n;
	cin >> n;
	for (int i = 0; i < n; ++i) cin >> q[i];
	quick_sort(q, 0, n - 1);
	for (int i = 0; i < n; ++i) cout << q[i] << " ";
}

2. Quick selection

Introduction: The quick selection algorithm is an algorithm with a time complexity of O(n) based on quick sorting. Its function is to find the kth smallest number in a sequence.

step:

  • In general, it is similar to the quick sort algorithm.
  • The difference is that if k is less than or equal to the length of the left half interval, recursively process the left half;
  • Otherwise, recursively process the right half.

Algorithm example:

const int N = 100010;
int q[N];

int quick_sort(int l, int r, int k)
{
    
    
	if (l == r) return q[l]; //可以以==,也可以>=
	int x = q[l + r >> 1], i = l - 1, j = r + 1;
	while (i < j) {
    
    
		while (q[++i] < x);
		while (q[--j] > x);
		if (i < j) swap(q[i], q[j]);
	}
	int sl = j - l + 1;//sl为左区间元素的个数
	if (k <= sl) return quick_sort(l, j, k);
	return quick_sort(j + 1, r, k - sl);
}

int main()
{
    
    
	int n, k;
	cin >> n >> k;
	for (int i = 0; i < n; ++i) cin >> q[i];
	cout << quick_sort(0, n - 1, k) <<endl;
}

3. Merge sort

Core idea: Merge two ordered and identical sequences into one ordered sequence

Specific steps:

  • Determine the cut-off point , divide the interval [l,r]into [l,mid]and[mid+1,r]
  • Recursive processing of left and right intervals [l,mid]and[mid+1,r]
  • Merge , merge two ordered ranges into one sorted range

Algorithm example:

const int N = 1e6 + 10;
int q[N], t[N];

void merge_sort(int* q, int l, int r)//归并排序模板
{
    
    
	if (l >= r) return;
	int mid = l + r >> 1;
	merge_sort(q, l, mid);
	merge_sort(q, mid + 1, r);
	int k = 0, i = l, j = mid + 1;
	while (i <= mid && j <= r)
	{
    
    
		if (q[i] <= q[j]) t[k++] = q[i++];
		else t[k++] = q[j++];
	}
	while (i <= mid) t[k++] = q[i++];
	while (j <= r) t[k++] = q[j++];
	for (int i = l, j = 0; i <= r; ++i, ++j) q[i] = t[j];
}

int main()
{
    
    
	int n;
	cin >> n;
	for (int i = 0; i < n; ++i) cin >> q[i];
	merge_sort(q, 0, n - 1);
	for (int i = 0; i < n; ++i) cout << q[i] << " ";
}

Fourth, the number of reverse order pairs

Reverse pair definition: two numbers, the former is greater than the latter, then these two numbers are called a reverse pair

Brief description: Find the number of reversed pairs in a sequence

Algorithm example:

typedef long long ll;//结果可能大于int的范围,函数返回值用long long类型
const int N = 100010;
int q[N], t[N];

ll merge_sort(int l, int r)
{
    
    
	if (l >= r) return 0;
	int mid = l + r >> 1;
	ll ret = merge_sort(l, mid) + merge_sort(mid + 1, r);
	int k = 0, i = l, j = mid + 1;
	while (i <= mid && j <= r) {
    
    
		if (q[i] <= q[j]) t[k++] = q[i++];
		else {
    
    
			t[k++] = q[j++];
			ret += mid - i + 1;
		}
	}
	while (i <= mid) t[k++] = q[i++];
	while (j <= r) t[k++] = q[j++];
	for (int i = l, j = 0; i <= r; ++i, ++j) q[i] = t[j];
	return ret;
}
int main()
{
    
    
	int n;
	cin >> n;
	for (int i = 0; i < n; ++i) cin >> q[i];
	cout << merge_sort(0, n - 1) << endl;
}

Guess you like

Origin blog.csdn.net/qq_52324409/article/details/122480940