算法基础学习|排序

快速排序

模板

void quick_sort(int q[], int l, int r)
{
    if (l >= r) return;

    int i = l - 1, j = r + 1, x = q[l + r >> 1];
    while (i < j)
    {
        do i ++ ; while (q[i] < x);
        do j -- ; while (q[j] > x);
        if (i < j) swap(q[i], q[j]);
    }
    quick_sort(q, l, j);
    quick_sort(q, j + 1, r);
}

实现代码

#include 
using namespace std;

void quick_sort(int q[], int l, int r)
{
    if (l >= r) return;

    int i = l - 1, j = r + 1, x = q[(l + r) / 2];
    while (i < j)
    {
        do i++; while (q[i] < x);
        do j--; 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;
    int* array = new int[n];
    for (int i = 0; i < n; i++) {
        cin >> array[i];
    }

    quick_sort(array, 0, n - 1);

    for (int i = 0; i < n; i++) {
        cout << array[i] << " ";
    }
    return 0;
}

例题

题目

给定一个长度为 n 的整数数列,以及一个整数 k ,请用快速选择算法求出数列从小到大排序后的第 k 个数。

输入格式

第一行包含两个整数 n 和 k

第二行包含 n 个整数(所有整数均在 1 ~ 10^9 范围内),表示整数数列。

输出格式

输出一个整数,表示数列的第 k 小数。

数据范围

1\leq n \leq 100000 ,

1\leq k \leq n

输入样例

5 3
2 4 1 5 3

输出样例

3

代码示例

#include 
using namespace std;

void quick_sort(int q[], int l, int r)
{
    if (l >= r) return;

    int i = l - 1, j = r + 1, x = q[(l + r) / 2];
    while (i < j)
    {
        do i++; while (q[i] < x);
        do j--; 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, k;
    cin >> n >> k;
	int* array = new int[n];
	for (int i = 0; i < n; i++) {
        cin >> array[i];
	}

    quick_sort(array, 0, n - 1);

    cout << array[k - 1];
    return 0;
}

归并排序

模板

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]) tmp[k ++ ] = q[i ++ ];
        else tmp[k ++ ] = q[j ++ ];

    while (i <= mid) tmp[k ++ ] = q[i ++ ];
    while (j <= r) tmp[k ++ ] = q[j ++ ];

    for (i = l, j = 0; i <= r; i ++, j ++ ) q[i] = tmp[j];
}

实现代码

#include 
using namespace std;

const int N = 1e6 + 10;

int tmp[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]) tmp[k++] = q[i++];
        else tmp[k++] = q[j++];

    while (i <= mid) tmp[k++] = q[i++];
    while (j <= r) tmp[k++] = q[j++];

    for (i = l, j = 0; i <= r; i++, j++) q[i] = tmp[j];
}


int main() {
    int n;
    cin >> n;
    int* array = new int[n];
    for (int i = 0; i < n; i++) {
        cin >> array[i];
    }

    merge_sort(array, 0, n - 1);

    for (int i = 0; i < n; i++) {
        cout << array[i] << " ";
    }
    return 0;
}

例题

题目

给定一个长度为 n 的整数数列,请你计算数列中的逆序对的数量。

逆序对的定义如下:对于数列的第 i 个和第 j 个元素,如果满足 i< j 且 a[i]>a[j],则其为一个逆序对;否则不是。

输入格式

第一行包含整数 n,表示数列的长度。

第二行包含 n 个整数,表示整个数列。

输出格式

输出一个整数,表示逆序对的个数。

数据范围

1\leq n \leq100000
数列中的元素的取值范围 \left [ 1, 10^9 \right ]

输入样例

6
2 3 4 5 6 1

输出样例

5

代码示例

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

const int N = 1e6 + 10;

typedef long long  LL;

int q[N], tmp[N];

LL merge(int l, int r) {
	if (l >= r) return 0;

	int mid = l + r >> 1;

	LL res = merge(l, mid) + merge(mid + 1, r);

	int k = 0, i = l, j = mid + 1;
	while (i <= mid && j <= r) {
		if (q[i] <= q[j]) tmp[k++] = q[i++];
		else {
			tmp[k++] = q[j++];
			res = mid - i + 1;
		}
	}

	while (i <= mid) tmp[k++] = q[i++];
	while (j <= r) tmp[k++] = q[j++];

	for (i = l, j = 0; i <= r; i++, j++) q[i] = tmp[j];

	return res;
}

int main() {
	int n;
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> q[i];
	}

	cout << merge(0, n - 1) << endl;

	return 0;
}

你可能感兴趣的:(Algorithm,算法,学习,java,C++,开发语言)