目录
一、递归的定义
1、什么时候会用到递归的方法
1. 定义是递归的
2. 数据结构是递归的
3. 问题的解法是递归的
2、应用递归的原则
3、递归调用顺序问题
1. 首先递归的过程可以总结为以下几点:
2. 递归工作栈
二、 递归和非递归的转化
1. 单向递归可用迭代
举例:斐波拉契数列
2. 尾递归可用迭代
举例:欧几里德求最大公约数
3. 借助栈实现非递归
1. 举例:二叉树的先序遍历
2. 举例:二叉树的中序遍历
三、分治解题步骤
四、汉诺塔问题
1. 问题
2. 解题思路
3. 两个盘子演示
4. 三个盘子演示
5. 四个盘子演示
6. 代码
定义:
求解函数:
int faction(int n)
{
if (n == 1)
return 1;
else
n = faction(n - 1) * n;
return n;
}
if (n == 1)
return 1;
这就是所谓的基本条件。
int BinSearch(int* data, int key,int low,int high)//折半查找
{
if (low > high)
return -1;
int mid = (low + high) / 2;
//二分查找递归的核心部分
if (key < data[mid])
return(data, key, low, mid - 1);//继续在data[low,mid-1]左区间查找
else if (key > data[mid])
return(data, key, mid + 1, high);//继续在data[mid+1,high]右区间查找
else
return mid;//查找成功
}
#include
using namespace std;
void Fuction1(int n)
{
if (n < 4)
{
printf("%d\n", n);
Fuction1(n + 1);
}
}
void Fuction2(int n)
{
if (n < 4)
{
Fuction2(n + 1);
printf("%d\n", n);
}
}
int main()
{
cout << "第一个函数:" << endl;
Fuction1(0);
cout << "第二个函数:" << endl;
Fuction2(0);
return 0;
}
int Fib(int n)
{
if (n < 2)
return n == 0 ? 0 : 1;
else if (n >= 2)
{
n = Fib(n - 1) + Fib(n - 2);
return n;
}
}
int Fib(int n)
{
vector v;
v.push_back(0);
v.push_back(1);
int i = 2;
for (i = 2; i <= n; i++)
{
int t = v[i - 1] + v[i - 2];
v.push_back(t);
}
return v[n];
}
int gcd(int a, int b)
{
if (b == 0)
return a;
else
gcd(b, a % b);
}
int gcd(int a, int b)
{
int tmp;//保存a%b
while (b!=0)
{
tmp = a % b;
a = b;
b = tmp;
}
return a;
}
void PreOrder(BTree T)//先序遍历
{
if (T != NULL)
{
cout << T->data << " ";//访问根结点
PreOrder(T->lchild);//先序遍历左子树
PreOrder(T->rchild);//先序遍历右子树
}
}
bool First(BTree T)
{
stacks;
BTNode* p = T;
if (p != NULL )//二叉树不为空
{
s.push(p);
while (!s.empty())//栈不为空
{
p = s.top();
cout << s.top()->data << " ";//先访问栈顶元素
s.pop();//栈顶元素退栈
if (p->lchild != NULL)
s.push(p->rchild);//栈顶元素的右孩子结点进栈
if (p->rchild != NULL)
s.push(p->lchild);//栈顶元素的左孩子结点进栈
}
}
return true;
}
void InOrder(BTree T)//中序遍历
{
if (T != NULL)
{
InOrder(T->lchild);
cout << T->data << " ";
InOrder(T->rchild);
}
}
bool InOder(BTree T)
{
stacks;
BTNode* p = T;
while (p != NULL || !s.empty())
{
while (p != NULL)//当前结点不为空
{
s.push(p);
p = p->lchild;
}
if (!s.empty())
{
cout << s.top()->data << " ";//访问栈顶元素
p = s.top()->rchild;//先将栈顶元素的右孩子存储起来
s.pop();//栈顶元素出栈
}
}
return true;
}
1. 分解:将要解决的问题分解为若干个规模较小、相互独立、与原问题形式相同的子问题
2. 治理:求解各个子问题。由于各个子问题与原问题形式相同,只是规模较小而已,而当子问题划分得足够小时,就可以用较简单的方法解决
3. 合并:按原问题的要求,将子问题的解逐层合并构成原问题的解
#include
using namespace std;
void Move(int n, char x, char y)
{
cout << "将编号为" << n << "的盘子从" << x << "移向" << y << endl;
}
void hanota(int n,char a,char b,char c)
{
if (n == 1)
Move(1, a, c);
else
{
hanota(n - 1, a, c, b);//将n-1个盘子从a移到b
Move(n, a, c);//将剩下的第n个盘子直接移到c处
hanota(n - 1, b, a, c);//又将n-1个盘子从b移到c
}
}
int main()
{
hanota(3, 'A', 'B', 'C');
return 0;
}