分治
时间复杂度在O(nlogn)~O(n^2)之间
1.确定分界点
2.调整区间
3. 递归(先处理左段,再处理右段)
785.快速排序
#include
using namespace std;
const int N = 1e6 + 10;
int n, q[N];
void quick_sort(int q[], int l, int r) {
if (l >= r) return;
int x = q[(l + r) / 2], i = l - 1, j = r + 1;
while (i < j) {
do i++; while (q[i] < x);//小于x,则左指针继续右移
do j--; while (q[j] > x);//当遇到大于等于x的数,右指针左移,遇到小于等于x的数则停下
if (i < j) 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++) scanf("%d", &q[i]);
quick_sort(q, 0, n - 1);
for (int i = 0; i < n; i++) printf("%d ", q[i]);
return 0;
}
786.第k个数
#include
using namespace std;
const int N = 100010;
int n, k, q[N];
void q_sort(int q[], int l, int r) {
if (l >= r) return;
int x = q[(l + r) / 2], i = l - 1, j = 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]);
}
q_sort(q, l, j);
q_sort(q, j + 1, r);
}
int main() {
cin >> n >> k;
for (int i = 0; i < n; i++) cin >> q[i];
q_sort(q, 0, n - 1);
//for (int i = 0; i < n; i++) cout << q[i] << endl;
cout << q[k - 1];
return 0;
}
分治、双指针
时间复杂度O(nlogn)
1.确定分界点,mid=(l+r)/2
2.递归排序
3.归并——合二为一
787.归并排序
#include
using namespace std;
const int N = 100010;
int n, 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);
//k记录当前的位置,i记录左段的指针位置,j记录右段的指针位置
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 (int i = l, j = 0; i <= r; i++, j++) q[i] = tmp[j];
}
int main() {
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] << " ";
return 0;
}