归并排序与快速排序
归并排序
// 归并排序 - 合并两个有序数组
void merge(vector<int>& arr, int l, int mid, int r) {
// 创建临时数组存储合并结果
vector<int> temp(r - l + 1);
int i = l, j = mid + 1, k = 0;
// 比较左右两部分的元素,按序放入临时数组
while(i <= mid && j <= r) {
if(arr[i] <= arr[j]) {
temp[k++] = arr[i++]; // 左半部分元素较小
} else {
temp[k++] = arr[j++]; // 右半部分元素较小
}
}
// 将左半部分剩余元素放入临时数组
while(i <= mid) temp[k++] = arr[i++];
// 将右半部分剩余元素放入临时数组
while(j <= r) temp[k++] = arr[j++];
// 将临时数组中的元素复制回原数组
for(int i = 0; i < k; i++) {
arr[l + i] = temp[i];
}
}
// 归并排序的递归实现
void mergeSort(vector<int>& arr, int l, int r) {
if(l >= r) return; // 递归终止条件:区间长度为1
int mid = l + (r - l >> 1); // 计算中点,防止溢出
mergeSort(arr, l, mid); // 递归排序左半部分
mergeSort(arr, mid + 1, r); // 递归排序右半部分
merge(arr, l, mid, r); // 合并两个有序数组
}
快速排序
void quickSort(vector<int>& arr, int l, int r) {
if(l >= r) return;
int x = arr[l + (r - l >> 1)];
int i = l, j = r;
while(i < j) {
while(arr[i] < x) i++;
while(arr[j] > x) j--;
if(i < j) swap(arr[i], arr[j]);
}
quickSort(arr, l, j);
quickSort(arr, j + 1, r);
}
// 快速排序的分区函数
// 将数组按照基准值分为两部分,返回分区点位置
int partition(vector<int>& arr, int l, int r) {
int x = arr[l + (r - l >> 1)]; // 选择中间位置的元素作为基准值
int i = l, j = r; // 双指针,从两端向中间移动
while(i < j) {
while(arr[i] < x) i++; // 找到左边第一个大于等于基准值的元素
while(arr[j] > x) j--; // 找到右边第一个小于等于基准值的元素
if(i < j) swap(arr[i], arr[j]); // 交换这两个元素
}
return j; // 返回分区点位置
}
// 快速排序的主函数
// 通过分治的方式递归排序数组
void quickSort(vector<int>& arr, int l, int r) {
if(l >= r) return; // 递归终止条件:区间长度为1
int x = partition(arr, l, r); // 获取分区点
quickSort(arr, l, x - 1); // 递归排序左半部分
quickSort(arr, x + 1, r); // 递归排序右半部分
}
题目
P1908 逆序对
思路
求逆序对的过程正好与归并排序相对应。利用分治思想,求左半边逆序对数+右半边逆序对数+跨边逆序对数,正好对应将左半边排序+右半边排序+数组合并。
示例代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
//#define int ll
#define pii pair<int, int>
#define all(x) x.begin(),x.end()
#define fer(i, m, n) for(int i = m; i < n; ++i)
#define ferd(i, m, n) for(int i = m; i >= n; --i)
#define dbg(x) cout << #x << ' ' << char(61) << ' ' << x << '\n'
const int MOD = 1e9 + 7;
const int N = 2e5 + 2;
const int inf = 1e9;
ll merge(vector<int> &arr, int l, int mid, int r) {
ll cnt = 0;
vector<int> temp(r - l + 1);
int i = l, j = mid + 1, k = 0;
while(i <= mid && j <= r) {
if(arr[i] <= arr[j]) temp[k++] = arr[i++];
else temp[k++] = arr[j++], cnt += mid - i + 1;
}
while(i <= mid) temp[k++] = arr[i++];
while(j <= r) temp[k++] = arr[j++];
fer(i, 0, k) arr[l + i] = temp[i];
return cnt;
}
ll mergeSort(vector<int> &arr, int l, int r) {
if(l >= r) return 0;
int mid = l + (r - l >> 1);
ll res = 0;
res += mergeSort(arr, l, mid);
res += mergeSort(arr, mid + 1, r);
res += merge(arr, l, mid, r);
return res;
}
signed main() {
ios::sync_with_stdio(false); cin.tie(nullptr);
int n;
cin >> n;
vector<int> arr(n);
fer(i, 0, n) cin >> arr[i];
cout << mergeSort(arr, 0, n - 1) << '\n';
return 0;
}

浙公网安备 33010602011771号