这里写目录标题
一 递归
递归算法:直接或者间接调用自身的算法称为递归算法
全排列问题
void Perm(int list[], int k, int m)//前缀[0:k-1],后缀[k,m]
{
if(k==m)
{ for(int i=0;i<=m;i++) cout<<list[i];
cout<<endl;
}
else
for(int i=k;i<=m;i++)
{
swap(list[k],list[i]);
Perm(list, k+1,m);
swap(list[k],list[i]);//恢复现场
}
}
Perm(list,0,n-1);
二 分治
1.该问题的规模缩小到一定的程度就可以容易地解决;
2.该问题可以分解为若干个规模较小的相同问题。
3.利用该问题分解出的子问题的解可以合并为该问题的解;
4.该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问题。
分治策略注意事项:
1子问题与原始问题性质完全一样
2 子问题之间可彼此独立地求解
3. 递归停止时子问题可直接求解。
棋盘覆盖问题
int title;
void chess(int tr,int tc,int dr,int dc,int size)//tr棋盘左上角,dr特殊方格
{
if(size==1)
return;
int s=size/2;
int t=title++;//每个L形骨牌三个位置,用同一个数字表示
//左上角
if(dr<tr+s&&dc<tc+s)//特殊方格在此棋盘
chess(tr,tc,dr,dc,s);//递归此小棋盘
else //没有特殊方格
{
b[tr+s-1][tc+s-1]=t;//将小棋盘中右下角,标记为特殊方格
chess(tr,tc,tr+s-1,tc+s-1,s);//递归此小棋盘,
//并将特殊方格dr,dc,用具体标记过的tr+s-1,tc+s-1表示
}
//右上角
if(dr<tr+s&&dc>=tc+s)
chess(tr,tc+s,dr,dc,s);
else
{
b[tr+s-1][tc+s]=t;
chess(tr,tc+s,tr+s-1,tc+s,s);
}
//左下角
if(dr>=tr+s&&dc<tc+s)
chess(tr+s,tc,dr,dc,s);
else
{
b[tr+s][tc+s-1]=t;
chess(tr+s,tc,tr+s,tc+s-1,s);
}
//右下角
if(dr>=tr+s&&dc>=tc+s)
chess(tr+s,tc+s,dr,dc,s);
else
{
b[tr+s][tc+s]=t;
chess(tr+s,tc+s,tr+s,tc+s,s);
}
}
合并排序
在这里插入代码片
归并排序
在这里插入代码片
快速排序
本质就是把基准数大的都放在基准数的右边,把比基准数小的放在基准数的左边,这样就找到了该数据在数组中的正确位置.
void Quick_Sort(int *arr, int begin, int end){
if(begin > end)
return;
int tmp = arr[begin];
int i = begin;
int j = end;
while(i != j){//相遇就退出
while(arr[j] >= tmp && j > i)
j--;
while(arr[i] <= tmp && j > i)
i++;
if(j > i){//走不动交换
int t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
}
arr[begin] = arr[i];//与基准数交换
arr[i] = tmp;
Quick_Sort(arr, begin, i-1);
Quick_Sort(arr, i+1, end);
}
循环赛日程表
在这里插入代码片