C++递归与分治算法原理示例详解

目录
  • 1. 汉诺塔问题
  • 2. 全排列问题
  • 4. 归并排序
  • 5. 快速排序
  • 6. 棋盘覆盖问题

1. 汉诺塔问题

递归算法,分为 3 步:将 n 个 a 上的盘子借助 c 移动到 b

① 将 n-1 个 a 上的盘子借助 b 移动到 c

② 将 a 上的盘子移动到 b

③ 将 c 上的 n-1 个盘子借助 a 移动到 b

所有盘子都移动到 b 上了

void hanoi(int n,char a,char b,char c)//将n个碟子从a借助c 移到b
 {
    if(n==0)
    return;
    else
     {
        hanoi(n-1,a,c,b);
        move(a,b);
        hanoi(n-1,c,b,a);
     }
}

2. 全排列问题

问题描述:设R={r1,r2,…,rn}是要进行排列的n个元素,求R的全排列Perm(R)。

算法思路:

① 从 n 个数中取出数列的第一个数,然后不断将数列中剩余的数与第一个数进行交换,计算剩余 n-1 个数的全排列。

② 对 n - 1 个数进行同样的递归操作,当交换的第一个数的下标 k 和 序列末尾的 m 相同时,说明前置所有数都已经交换完成,进行输出。

③ 递归结束后进行状态回调,保证不影响下一次递归的进行。

void Perm(int list[], int k, int m)
{
    if(k==m)
    {
        for(int i=0;i<m;i++)
        {
            cout<<list[i];
        }
        cout<<endl;
        return;
    }
    for(int i=k;i<m;i++)
    {
        swap(list[k], list[i])
        Perm(list, k+1, m)
        swap(list[k], list[i])
    }
}

3. 利用递归与分治策略寻找最大值

#include <bits/stdc++.h>
using namespace std;
int find_max(int a[], int from, int to){
    if(from>=to) return a[from];
    int mid = (from + to)/2;
    int v1 = find_max(a, from, mid);
    int v2 = find_max(a, mid+1, to);
    if(v1<=v2) return v2;
    else return v1;
}
int main()
{
    int n, a[100000];
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    cout<<find_max(a, 0, n-1);
}

4. 归并排序

#include <bits/stdc++.h>
using namespace std;
void merge_array(int a[], int from, int mid, int to){

    int tmp[100000], idx_tmp=0;
    int i,j;
    for(i=from, j=mid+1; i<=mid && j<=to;){

        if(a[i]<=a[j]) tmp[idx_tmp++] = a[i++];
        else tmp[idx_tmp++] = a[j++];
    }
    while(i<=mid) tmp[idx_tmp++]=a[i++];
    while(j<=to) tmp[idx_tmp++]=a[j++];
    for(int i=from,j=0; i<=to;i++) a[i] = tmp[j++];
}

void merge_sort(int a[], int from, int to){
    if(from < to){
        int mid = (from + to)/2;
        merge_sort(a, from, mid);
        merge_sort(a, mid+1, to);
        merge_array(a, from, mid, to);
    }
}
int main()
{
    int n, a[100000];
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    merge_sort(a, 0, n-1);
    for(int i=0;i<n;i++){
        printf("%d ", a[i]);
    }
}

5. 快速排序

图解快速排序://www.jb51.net/article/113769.htm

递归 + 交换法

#include <bits/stdc++.h>
using namespace std;
int sort_array(int a[], int from, int to)
{
    int base = a[from];
    int i,j;
    for(i=from, j=to; i<j;)
    {
        while(a[j]>=base && i<j) j--;
        while(a[i]<=base && i<j) i++;
        //function swap()
        if(i<j){
            int t=a[i];
            a[i]=a[j];
            a[j]=t;
        }
    }
    a[from]=a[i];
    a[i]=base;
    return i;
}
void quick_sort(int a[], int from, int to)
{
    if(from>=to) return;
    int i = sort_array(a, from, to);
    quick_sort(a, from, i-1);
    quick_sort(a, i+1, to);
}

int main()
{
    int n, a[100000];
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    quick_sort(a, 0, n-1);
    for(int i=0;i<n;i++){
        printf("%d ", a[i]);
    }
}

6. 棋盘覆盖问题

#include <bits/stdc++.h>
using namespace std;
int num=0;
int a[1000][1000];
void make_chess(int px, int py, int tx, int ty, int sze){
    if(sze==1) return;
    num++;
    sze/=2;

    //左上
    if(px<tx+sze && py<ty+sze)
    {
        a[tx+sze-1][ty+sze]=num;
        a[tx+sze][ty+sze-1]=num;
        a[tx+sze][ty+sze]=num;
    }

    //右上
    if(px<tx+sze && py>=ty+sze)
    {
        a[tx+sze-1][ty+sze-1]=num;
        a[tx+sze][ty+sze-1]=num;
        a[tx+sze][ty+sze]=num;
    }

    //左下
    if(px>=tx+sze && py<ty+sze)
    {
        a[tx+sze-1][ty+sze-1]=num;
        a[tx+sze-1][ty+sze]=num;
        a[tx+sze][ty+sze]=num;
    }
    //右下
    if(px>=tx+sze && py>=ty+sze)
    {
        a[tx+sze-1][ty+sze-1]=num;
        a[tx+sze-1][ty+sze]=num;
        a[tx+sze][ty+sze-1]=num;
    }

    //左上
    if(px<tx+sze && py<ty+sze) make_chess(px, py, tx, ty, sze);
    else make_chess(tx+sze-1, ty+sze-1, tx, ty, sze);

    //右上
    if(px<tx+sze && py>=ty+sze) make_chess(px, py, tx, ty+sze,sze);
    else make_chess(tx+sze-1, ty+sze, tx, ty+sze,sze);

    //左下
    if(px>=tx+sze && py<ty+sze) make_chess(px, py, tx+sze, ty,sze);
    else make_chess(tx+sze, ty+sze-1, tx+sze, ty, sze);

    //右下
    if(px>=tx+sze && py>=ty+sze) make_chess(px, py, tx+sze, ty+sze, sze);
    else make_chess(tx+sze, ty+sze, tx+sze, ty+sze, sze);
}

int main()
{
    int k, px, py;
    int tx=0, ty=0;
    cin>>k>>px>>py;
    make_chess(px-1, py-1, tx, ty, k);

    for(int i=0; i<k; i++){
        for(int j=0; j<k; j++){
            printf("%2d ", a[i][j]);
        }
        cout<<endl;
    }
}

以上就是C++递归与分治算法原理示例详解的详细内容,更多关于C++递归与分治算法的资料请关注我们其它相关文章!

(0)

相关推荐

  • C++ 汉诺塔问题知识点总结

    汉诺塔问题,是心理学实验研究常用的任务之一.当然我们是学计算机的,因此我们尝试用计算机去求解它. 例题 openjudge6261 汉诺塔问题 描述 有一种智力玩具,在一块铜板上有三根杆,最左边的杆上自上而下.由小到大顺序串着由n个圆盘构成的塔.目的是将最左边杆上的盘全部移到中间的杆上,条件是一次只能移动一个盘,且不允许大盘放在小盘的上面.这就是著名的汉诺塔问题. 假定圆盘从小到大编号为1,2,3,-- 输入 输入为一个整数后面跟三个单字符字符串. 整数为盘子的数目,后三个字符表示三个杆子的编号

  • C#递归算法之分而治之策略

    1.分而治之的概念   分而治之是一种使用递归解决问题的算法,主要的技巧是将一个大的复杂的问题划分为多个子问题,而这些子问题可以作为终止条件,或者在一个递归步骤中得到解决,所有子问题的解决结合起来就构成了对原问题的解决 2.分而治之的优点和缺点 分而治之算法通常包括一个或者多个递归方法的调用,当这些调用将数据分隔成为独立的集合从而处理较小集合的时候,分而治之的策略将会有很高的效率,而在数据进行分解的时候,分而治之的策略可能会产生大量的重复计算,从而导致性能的降低. 3.画标尺程序的分析讲解 画标

  • c++动态规划经典算法

    目录 基本思想 重要分析问题方法 动态规划算法实例 1.台阶问题 2.从矩阵左上角走到右下角最短路径问题 3.最大子数组问题 4.最长公共子序列 基本思想 动态规划算法通常用于求解具有某种最优性质的问题.在这类问题中,可能会有许多可行解.每一个解都对应于一个值,我们希望找到具有最优值的解.动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解.与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的.若用分

  • C++递归算法实例代码

    递归算法,总结起来具有以下几个特点: 特点1  它有一个基本部分,即直接满足条件,输出     特点2  它有一个递归部分,即 通过改变基数(即n),来逐步使得n满足基本部分的条件,从而输出     特点3  在实现的过程中,它采用了分治法的思想:        即将整体分割成部分,并总是从最小的部分(基本部分)开始入手(输出),其背后的原理在于 当整体递归到部分时,会保留整体的信息,部分满足条件输出的结果会被回溯给整体使用,从而使得整体输出结果.     特点4  每一步操作,整体都会将部分当

  • C++递归与分治算法原理示例详解

    目录 1. 汉诺塔问题 2. 全排列问题 4. 归并排序 5. 快速排序 6. 棋盘覆盖问题 1. 汉诺塔问题 递归算法,分为 3 步:将 n 个 a 上的盘子借助 c 移动到 b ① 将 n-1 个 a 上的盘子借助 b 移动到 c ② 将 a 上的盘子移动到 b ③ 将 c 上的 n-1 个盘子借助 a 移动到 b 所有盘子都移动到 b 上了 void hanoi(int n,char a,char b,char c)//将n个碟子从a借助c 移到b { if(n==0) return; e

  • Python中八大图像特效算法的示例详解

    目录 0写在前面 1毛玻璃特效 2浮雕特效 3油画特效 4马赛克特效 5素描特效 6怀旧特效 7流年特效 8卡通特效 0 写在前面 图像特效处理是基于图像像素数据特征,将原图像进行一定步骤的计算——例如像素作差.灰度变换.颜色通道融合等,从而达到期望的效果.图像特效处理是日常生活中应用非常广泛的一种计算机视觉应用,出现在各种美图软件中,这些精美滤镜背后的数学原理都是相通的,本文主要介绍八大基本图像特效算法,在这些算法基础上可以进行二次开发,生成更高级的滤镜. 本文采用面向对象设计,定义了一个图像

  • JavaScript实现基础排序算法的示例详解

    目录 前言 正文 1.冒泡排序 2.选择排序 3.插入排序 4.快速排序 前言 文本来总结常见的排序算法,通过 JvavScript  来实现 正文 1.冒泡排序 算法思想:比较相邻两个元素的大小,如果第一个比第二个大,就交换它们.从头遍历到尾部,当一轮遍历完后,数组最后一个元素是最大的.除去最后一个元素,对剩下的元素重复执行上面的流程,每次找出剩余元素中最大的,遍历完后,数组是升序的 算法分析:总共需要进行length * (length - 1) / 2 次比较,所以时间复杂度为O(n^2)

  • Sentinel熔断规则原理示例详解分析

    目录 概述 熔断(降级)策略 慢调用比例 概念 测试 异常比例 概念 测试 异常数 概念 测试 概述 除了流量控制以外,对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措施之一. 由于调用关系的复杂性,如果调用链路中的某个资源不稳定,最终会导致请求发生堆积. Sentinel 熔断降级会在调用链路中某个资源出现不稳定状态时(例如调用超时.异常比例升高.异常数堆积) 对这个资源的调用进行限制,让请求快速失败从而避免影响到其它的资源而导致级联错误. 当资源被降级后,在接下来的降级时间窗口之内

  • C语言实现冒泡排序算法的示例详解

    目录 1. 问题描述 2. 问题分析 3. 算法设计 动图演示 4. 程序设计 设计一 设计二 结论 5. 流程框架 6. 代码实现 7. 问题拓展 1. 问题描述 对N个整数(数据由键盘输入)进行升序排列. 2. 问题分析 对于N个数因其类型相同,我们可利用 数组 进行存储. 冒泡排序是在 两个相邻元素之间进行比较交换的过程将一个无序表变成有序表. 冒泡排序的思想:首先,从表头开始往后扫描数组,在扫描过程中逐对比较相邻两个元素的大小. 若相邻两个元素中,前面的元素大于后面的元素,则将它们互换,

  • Kotlin协程Dispatchers原理示例详解

    目录 前置知识 demo startCoroutineCancellable intercepted()函数 DefaultScheduler中找dispatch函数 Runnable传入 Worker线程执行逻辑 小结 前置知识 Kotlin协程不是什么空中阁楼,Kotlin源代码会被编译成class字节码文件,最终会运行到虚拟机中.所以从本质上讲,Kotlin和Java是类似的,都是可以编译产生class的语言,但最终还是会受到虚拟机的限制,它们的代码最终会在虚拟机上的某个线程上被执行. 之

  • C++实现贪心算法的示例详解

    目录 区间问题 区间选点 最大不相交区间数量 区间分组 区间覆盖 Huffman树 合并果子 排序不等式 排队打水 绝对值不等式 货舱选址 区间问题 区间选点 给定 N 个闭区间 [ai,bi],请你在数轴上选择尽量少的点,使得每个区间内至少包含一个选出的点. 输出选择的点的最小数量. 位于区间端点上的点也算作区间内. 输入格式 第一行包含整数 N,表示区间数. 接下来 N 行,每行包含两个整数 ai,bi,表示一个区间的两个端点. 输出格式 输出一个整数,表示所需的点的最小数量. 数据范围 1

  • Flutter 弹性布局基石flex算法flexible示例详解

    目录 flex 布局算法 非弹性组件在 main 轴受到的约束是 unbounded fit 参数 Expanded Spacer flex 布局算法 Flutter 弹性布局的基石 是 flex 和 flexible.理解了这两个 widget,后面的row,column 就都轻而易举了.本文用示例的方式详细介绍 flex 的布局算法. 先布局 flex 为 0 或 null 的 child.在 main 轴上 child 受到的约束是 unbounded.如果 crossAxisAlignm

  • Array.reduce使用原理示例详解

    目录 正文 重新了解 Array.reduce reduce 的运用场景 用于计算数据 将多维数组转为一维数组 将函数作为参数 其他场景 最后 正文 我们经常会用到 Array 对象的 reduce 方法,把它用于做一些计算.或者数据组合,发现自己用了那么多年 reduce ,竟然还不是很了解它,最近才发现如果不传递初始值,它也可以正常进行,数组也可以是一个函数数组,来增强我们的代码. 本篇文章将带你重来了解 Array.reduce 和运用场景. 重新了解 Array.reduce 我们来看一

  • 通俗易懂的C++前缀和与差分算法图文示例详解

    目录 1.前缀和 2.前缀和算法有什么好处? 3.二维前缀和 4.差分 5.一维差分 6.二维差分 1.前缀和 前缀和是指某序列的前n项和,可以把它理解为数学上的数列的前n项和,而差分可以看成前缀和的逆运算.合理的使用前缀和与差分,可以将某些复杂的问题简单化. 2.前缀和算法有什么好处? 先来了解这样一个问题: 输入一个长度为n的整数序列.接下来再输入m个询问,每个询问输入一对l, r.对于每个询问,输出原序列中从第l个数到第r个数的和. 我们很容易想出暴力解法,遍历区间求和. 代码如下: in

随机推荐