蒟蒻の分治算法总结

分治算法定义

将一个问题分解成多个子问题,将问题缩小到一定规模后逐个求解,最后合并所有子问题

分治算法步骤

  1. 分解(将原问题分解成一个形式相同规模更小的子问题)
  2. 解决(递归求解子问题,直到问题的规模足够小,直接求解)
  3. 合并(合并子问题的解,得到原问题的解)

分治算法例题(实际应用)

插入排序

思路

一道十分普通的 O ( n 2 ) O(n^2) O(n2)时间复杂度题,使用类似打扑克牌时给牌排序的分治思想递归实现即可

即:

先给n-1张牌排序,再分成给n-2张牌排序,以此类推…

直到只剩1张牌,则直接结束

Code

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,a[110];
 4 void insert_sort(int a[],int n){
 5     //1.基本情况 
 6     if(n==1)return;
 7     //2.分解子问题 
 8     //3.解决子问题 
 9     insert_sort(a,n-1);
10     int tmp=a[n],i; 
11     for(i=n-1;i>=1;i--){
12         if(a[i]>tmp){
13             a[i+1]=a[i];
14         }else{
15             break;
16         }
17     }
18     a[i+1]=tmp;
19 }
20 int main(){
21     scanf("%d",&n);
22     for(int i=1;i<=n;i++){
23         scanf("%d",&a[i]);
24     }
25     insert_sort(a,n);
26     for(int i=1;i<=n;i++){
27         printf("%d ",a[i]);
28     }
29     return 0;
30 }
View Code

 

归并排序

思路

这道题的数据范围加大,不能再用 O ( n 2 ) O(n^2) O(n2)算法解决,会导致TLE;故我们可以用归并排序解决

图解

  Code

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,a[110],b[110];
 4 void merge(int a[],int l,int mid,int r,int t[]){
 5     int i=l,j=mid+1,k=l;
 6     while(i<=mid&&j<=r){
 7         if(a[i]<=a[j])t[k++]=a[i++];
 8         else t[k++]=a[j++];
 9     }
10     while(i<=mid)t[k++]=a[i++];
11     while(j<=r)t[k++]=a[j++];
12     for(i=l;i<=r;i++)a[i]=t[i];
13 }
14 void merge_sort(int a[],int l,int r,int t[]){
15     //1.基本情况 
16     if(l==r)return;
17     //2.分解子问题 
18     int mid=(l+r)>>1;
19     //3.解决子问题 
20     merge_sort(a,l,mid,t);
21     merge_sort(a,mid+1,r,t);
22     //4.合并子问题的解 
23     merge(a,l,mid,r,t);
24 }
25 int main(){
26     scanf("%d",&n);
27     for(int i=1;i<=n;i++){
28         scanf("%d",&a[i]);
29     }
30     merge_sort(a,1,n,b);
31     for(int i=1;i<=n;i++){
32         printf("%d ",a[i]);
33     }
34     return 0;
35 }
View Code

 

快速排序

思路

使用 O ( n log ⁡ n ) O(n \log n) O(nlogn)时间复杂度的快速排序,具体步骤看下图

Code

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,a[100010];
 4 void quick_sort(int a[],int l,int r){
 5     //1.基本情况 
 6     if(l==r)return;//可省略
 7     //2.分解子问题 
 8     int i=l,j=r,mid=a[l+rand()%(r-l+1)];
 9     while(i<=j){
10         while(a[i]<mid)i++;
11         while(a[j]>mid)j--;
12         if(i<=j){
13             swap(a[i],a[j]);
14             i++;
15             j--;
16         }
17     }
18     //3.解决子问题 
19     if(l<j)quick_sort(a,l,j);
20     if(i<r)quick_sort(a,i,r);
21     //4.合并子问题的解 
22 }
23 int main(){
24     scanf("%d",&n);
25     for(int i=1;i<=n;i++){
26         scanf("%d",&a[i]);
27     }
28     quick_sort(a,1,n);
29     for(int i=1;i<=n;i++){
30         printf("%d ",a[i]);
31     }
32     return 0;
33 }
View Code

 

posted @ 2020-09-05 10:31  小罐猹  阅读(57)  评论(0编辑  收藏  举报