分治
思想:将一个较大的问题分解成若干个较小的问题,分而治之。
步骤:
1.分解:将要解决的问题分解为若干个规模较小、相互独立、与原问题形式相同的子问题。
2.治理:求解各个子问题。由于各个子问题与原问题形式相同,只是规模较小而已,而当子问题划分得足够小时,就可以用简单的方法解决。
3.合并:按原问题的要求,将子问题的解逐层合并构成原问题的解。
快速排序
快速排序步骤:
1.找到基准数tmp
2.左边所有数left <= tmp, 右边所有数right >= tmp
3.递归排序left, 递归排序right
快速排序模板
#include<bits/stdc++.h>
using namespace std;
int a[101],n;
void quicksort(int left,int right){
int i,j,temp;
if (left>right) return;
temp = a[left]; //temp存基准数
i = left;
j = right;
while (i!=j){
//顺序很重要,先从右边找,再从左边找
while (a[j] >= temp && i<j) j--;
while (a[i] <= temp && i<j) i++;
//交换数组中i、j位置上的数
if (i<j){
int t=a[i];
a[i] = a[j];
a[j] = t;
}
}
//将基准数归位
a[left] = a[i];
a[i] = temp;
//继续处理左右两边
quicksort(left,i-1);
quicksort(i+1,right);
}
int main(){
//输入数据
cin>>n;
for (int i=0;i<n;i++) cin>>a[i];
quicksort(0,n-1);//调用函数
for (int i=0;i<n;i++) cout<<a[i]<<" ";
return 0;
}
扩展:快速查找模板
#include<bits/stdc++.h>
using namespace std;
int q[101],n,k;
//寻找第 d 小的数
int quick_sort(int l,int r,int d){
if (l >= r) return q[l];
int temp=q[l],i=l-1,j=r+1;
while (i<j){
while (q[ ++ i]<temp);
while (q[ -- j]>temp);
if (i<j) swap(q[i], q[j]);//交换i,j位置上的数
}
int l_len=j-l+1;//计算左边部分的长度
if (d<=l_len) return quick_sort(l,j,d);//如果低 d 小的数在左边,就递归左边
return quick_sort(j+1,r,d-l_len);//否则递归右边
}
int main(){
cin>>n>>k;
for (int i=0;i<n;i++) cin>>q[i];
cout<<quick_sort(0,n-1,k);
return 0;
}
归并排序
归并排序步骤:
1.将整个区间一分为二( [l,r] -> [l,mid] [mid+1,r] )
2.递归排序 [l,mid] 和 [mid+1,r]
3.归并,将左右两个有序序列合并成一个有序序列
归并排序模板
#include<iostream>
using namespace std;
int tmp[101],q[101],n;
void merge(int l,int r){
if(l>=r) return;
//将数组分为两段
int mid=(l+r)>>1;
merge(l,mid);
merge(mid+1,r);
//归并的过程
int i=l,j=mid+1,k=l;
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;i<=r;i++) q[i]=tmp[i];
return;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++) cin>>q[i];
merge(1,n);//调用函数
for(int i=1;i<=n;i++) cout<<q[i]<<" ";
return 0;
}
扩展:寻找逆序对模板
#include<bits/stdc++.h>
using namespace std;
int n,q[101],tmp[101];
int merge_sort(int l,int r){
if (l>=r) return 0;
int mid = l + r >> 1;
int res = merge_sort(l,mid) + merge_sort(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 (int i=1,j=0;i<=r;i++,j++) q[i] = tmp[j];
return res;
}
int main(){
cin>>n;
for (int i=0;i<n;i++) cin>>q[i];
cout<<merge_sort(0,n-1);
return 0;
}