前言 本文及其系列文章为作者学习算法时的笔记,略显潦草,如有错误,请及时指正,持续更新中······
快速排序(基于分治)
思路:(l : 左 , r : 右)
1、确定分界点x : q[ l ] , q[ (l + r)/2] , q[ r ] , 随机
2*、调整区间 ( i<=x )( j>=x )
3、递归处理左右两段
实现方法(暴力)
1、a[ ] , b[ ]
2、 / q[ i ]<=x , x->a[ ]
q[ l~r ]
\ q[ i ]>=x , x->b[ ]
3、a[ ]->q[ ] , b[ ]->q[ ]
实现方法(优美)
1、i=l , j=r
2、 若q[ i ]<x , ++i 直至 q[ i ]>x ,
执行 若q[ j ]>x , ++j 直至 q[ i ]<x , 若i>=j
执行 swap(q[ i ] , q[ j ]) , ++i , ++ j
重复以上操作 , 直至i , j相遇 ( i>=j ) 为止
3、递归处理左右两段{ ( l~j )( j+1~r ) or ( l~i-1 )( i~r ) }重复以上操作 ( 注意考虑避开边界问题导致的死循环 : x=q[ l ]时 , 边界不能用第二种 , x=q[ r ]时 , 边界不能用第一种 )
代码实现
#include <iostream>
using namespace std;
const int N = 1e6 + 100;
int n;
int q[N];
void quick_sort(int q[], int l, int r) {
if (l >= r)return;
int x = q[l],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]);
}
quick_sort(q, l, j);
quick_sort(q, j + 1, r);
}
int main() {
scanf_s("%d", &n);
for (int i = 0; i < n; i++)scanf_s("%d", &q[i]);
quick_sort(q, 0, n-1);
for (int i = 0; i < n; i++)printf("%d ", q[i]);
return 0;
}
归并排序(基于分治)
思路:(l : 左 , r : 右)
1、确定分界点 : mid=( l+r )/2
2、递归处理左右两段
3*、归并 ( 合二为一 , 把两个有序数组和并成一个有序的数组 )
实现方法
略
代码实现
#include <iostream>
using namespace std;
const int N = 1e6 + 100;
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;//(>>1)<=>(/2)
merge_sort(q, l, mid);
merge_sort(q, mid + 1, r);
int k = 0, i = l, j = mid;
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() {
scanf_s("%d", &n);
for (int i = 0; i < n; i++)scanf_s("%d", &q[i]);
merge_sort(q, 0, n - 1);//归并排序
for (int i = 0; i < n; i++)printf("%d ", q[i]);
return 0;
}