第一章 基础算法
AcWing基础算法
代码模板要理解背过
课下把思想搞懂,能默写出来
代码删掉重复写三四遍就差不多
第一节课
排序
快速排序
算法模板:
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) {
//TODO
swap(q[i], q[j]); // swap()函数
}
quick_sort(q, l, j); // 为什么选择j ?
quick_sort(q, j + 1, r);
}
}
//交换两个数
if(i<j){
//TODO
int t=q[i];
q[i]=q[j];
q[j]=t;
}
例题: 785. 快速排序
题解:
#include<iostream>
using namespace std;
const int N = 1e6 + 10;
int n;
int q[N];
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) {
//TODO
swap(q[i], q[j]);
}
quick_sort(q, l, j);
quick_sort(q, j + 1, r);
}
}
int main() {
scanf("%d", &n);
for (int i = 0; i < n; i++) {
//TODO
scanf("%d", &q[i]);
}
quick_sort(q, 0, n - 1);
for (int i = 0; i < n; i++) {
//TODO
printf("%d ", q[i]);
}
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;// i是左半边区间的左边界,j是右半边区间的右边界。
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++];
}
// tmp[]数组元素复制存储到原数组q[],还原
for(i=l,j=0;i<=r;i++,j++){
q[i]=tmp[j];
}
}
快速排序是稳定的
归并排序是不稳定的
若想要快排稳定,只要让快排数组中每个数都不同,设置一个双元组,把下标也放进去,形成pair()
例题:787. 归并排序
题解:
#include<iostream>
using namespace std;
const int N = 100010;
int n;
int q[N], 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++];
}
// tmp[]数组元素复制存储到原数组q[]
for (i = l, j = 0; i <= r; i++, j++) {
q[i] = tmp[j];
}
}
int main() {
scanf("%d", &n);
for (int i = 0; i < n; i++) {
//TODO
scanf("%d", &q[i]);
}
merge_sort(q, 0, n - 1);
for (int i = 0; i < n; i++) {
//TODO
printf("%d ", q[i]);
}
return 0;
}
二分
整数二分
会有很多边界问题
有单调性的题目一定可以二分
算法模板:
bool check(int x) {
// 检查x是否满足某种性质