算法导论 第二章 递归与分治

阶乘函数  斐波那契数列

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

// 阶乘函数
int fact(int n)
{
    if(!n) return 1;
    return n * fact(n-1);
}

// 斐波那契数列
int fib(int n)
{
    if(n <= 1) return 1;
    return fib(n-1)+fib(n-2);
}

int main()
{
    cout << "fact(5) "<<fact(5) <<endl;
    cout << "fib(5) "<<fib(5) <<endl;
    return 0;
}
阶乘 斐波那契

 

排列问题

#include <iostream>
#include <cstring>
#include <algorithm>
#include <math.h>
using namespace std;
// 数组长度 排列总数
int n, ans;

/**
 *@param s 数组首地址
 *@param k 已经匹配完成[0,k-1] 
 *@param n 数组总长度
 */
 
 
void Perm(int *s,int k, int n)
{
    if(k >= n) {
        for(int i=0; i<=n; i++) {
            cout<< s[i] <<" ";
        }
        cout<< endl;
        ans++;
        return ;
    }
    for(int i=k; i<=n; i++) {
        swap(s[k], s[i]);
        Perm(s, k+1, n);
        swap(s[k], s[i]);
    }
}
int main()
{
    // 输入数组长度 并输入相应数量的数
    cin >> n;
    int *s = new int[n];
    for(int i=0;i<n;i++) {
        cin >> s[i];
    }
    // 对输入的数 进行排序
    sort(s, s+n);
    cout <<endl;
    Perm(s, 0, n-1);
    cout << "排列总数 " << ans<<endl;
    return 0;
}
排列问题 对以后的排列树有前置作用

 

整数划分

#include <iostream>
#include <cstring>
#include <algorithm>
#include <math.h>
using namespace std;

// 整数划分问题

/**
  *f(n,m)代表  n的整数划分中  最大的数不超过m的方案数
  */
int f(int n, int m)
{
    // n或m 有0 的情况了 就代表没有合法方案了
    if(n < 1 || m < 1)  
        return 0;
    // 显然 1的划分方案只有1种
    if(n == 1 && m == 1)
        return 1;
    // 如果划分的最大数 超过了n 方案数自然是 f(n,n)
    // 因为n划分不出比n的划分数了
    if(n < m)
        return f(n,n);
    // 如若 n = m 那么显然有一种方案 n = n 另外的方案 就是 f(n, n-1) 
    if(n == m) 
        return f(n,n-1) + 1;
    // 考虑最大划分数 小于m 和 等于m的方案数加和
    return f(n, m-1) + f(n-m, m);
}

int main()
{
    int n; cin >> n;
    cout << f(n, n) <<endl;
    return 0;
}
整数划分

 

汉诺塔问题

#include <iostream>
#include <cstring>
#include <algorithm>
#include <math.h>
using namespace std;

// 汉诺塔问题
char str[] = {' ', 'A', 'B', 'C'};
void mov(int a, int b, int n) 
{
    cout << str[a] <<"上的" <<n <<"号盘子"<<"->"<< str[b] <<""<<endl;
}

// A移到B 借助C
void hanoi(int n,int a,int b,int c)
{
    if(n) {
        hanoi(n-1, a, c, b);
        mov(a, b, n);
        hanoi(n-1, c, b ,a);
    }
}

int main()
{
    int n; 
    cin >> n;
    hanoi(n, 1, 2, 3);
    return 0;
}
汉诺塔

 

二分问题

#include <iostream>
#include <cstring>
#include <algorithm>
#include <math.h>
using namespace std;

int n,k;

int Find(int *s, int l, int r, int k)
{
    if(l > r)
        return -1;
    int mid = (l+r)/2;
    if(s[mid] == k) 
        return mid;
    else if(s[mid] > k) 
        return Find(s, l, mid-1, k);
    else 
        return Find(s, mid+1, r, k);
}

int main()
{
    cin >> n >> k;
    int *s = new int [n];
    for(int i=0; i<n; i++) {
        cin >> s[i];
    }
    sort(s, s+n);
    int c = Find(s, 0, n-1, k);
    if(c!=-1)
        cout << c <<endl;
    else 
        cout<<"没有找到"<<endl;
    return 0;
}
二分递归版

非递归 迭代版 见 链接 :https://www.cnblogs.com/Draymonder/p/7245930.html

posted @ 2018-11-21 20:32  Draymonder  阅读(215)  评论(0编辑  收藏  举报