分治算法总结

分治算法定义

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

分治算法步骤

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

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

插入排序

思路

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

即:

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

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

\(Code\)

#include<bits/stdc++.h>
using namespace std;
int n,a[110];
void insert_sort(int a[],int n){
	//1.基本情况 
	if(n==1)return;
	//2.分解子问题 
	//3.解决子问题 
	insert_sort(a,n-1);
	int tmp=a[n],i; 
	for(i=n-1;i>=1;i--){
		if(a[i]>tmp){
			a[i+1]=a[i];
		}else{
			break;
		}
	}
	a[i+1]=tmp;
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
	insert_sort(a,n);
	for(int i=1;i<=n;i++){
		printf("%d ",a[i]);
	}
	return 0;
}

归并排序

思路

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

图解

\(Code\)

#include<bits/stdc++.h>
using namespace std;
int n,a[110],b[110];
void merge(int a[],int l,int mid,int r,int t[]){
	int i=l,j=mid+1,k=l;
	while(i<=mid&&j<=r){
		if(a[i]<=a[j])t[k++]=a[i++];
		else t[k++]=a[j++];
	}
	while(i<=mid)t[k++]=a[i++];
	while(j<=r)t[k++]=a[j++];
	for(i=l;i<=r;i++)a[i]=t[i];
}
void merge_sort(int a[],int l,int r,int t[]){
	//1.基本情况 
	if(l==r)return;
	//2.分解子问题 
	int mid=(l+r)>>1;
	//3.解决子问题 
	merge_sort(a,l,mid,t);
	merge_sort(a,mid+1,r,t);
	//4.合并子问题的解 
	merge(a,l,mid,r,t);
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
	merge_sort(a,1,n,b);
	for(int i=1;i<=n;i++){
		printf("%d ",a[i]);
	}
	return 0;
}

快速排序

思路

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

\(Code\)

#include<bits/stdc++.h>
using namespace std;
int n,a[100010];
void quick_sort(int a[],int l,int r){
	//1.基本情况 
	if(l==r)return;//可省略
	//2.分解子问题 
	int i=l,j=r,mid=a[l+rand()%(r-l+1)];
	while(i<=j){
		while(a[i]<mid)i++;
		while(a[j]>mid)j--;
		if(i<=j){
			swap(a[i],a[j]);
			i++;
			j--;
		}
	}
	//3.解决子问题 
	if(l<j)quick_sort(a,l,j);
	if(i<r)quick_sort(a,i,r);
	//4.合并子问题的解 
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
	quick_sort(a,1,n);
	for(int i=1;i<=n;i++){
		printf("%d ",a[i]);
	}
	return 0;
}
posted @ 2020-09-05 10:31  小罐猹  阅读(240)  评论(0编辑  收藏  举报