数据结构---栈与递归
目录
栈与递归
递归:若在一个函数、 过程或者数据结构定义的内部又直接(或间接)出现定义本身的应用,则称它们是递归的
1.定义是递归的
如:阶乘函数,Fibonacci数列
分治法:复杂的问题能够分解成相对简单且解法相同或类似的子问题来求解
void p(参数表)
{
if(递归结束条件成立)可直接求解;
else p(较小的参数);
}
2.数据结构是递归的
如:链表的定义,遍历输出链表中各个结点的递归算法
3.问题的解法是递归的
如:Hanoi塔问题、八皇后问题、迷宫问题
递归过程与递归工作栈
在编写程序的过程中,调用函数和被调用函数之间的链接和信息交换需通过栈来进行
运行被调用函数之前:
- 将所有实参,返回地址等信息传递给被调用函数保存;
- 为被调用函数的局部变量分配存储区;
- 将控制转移到被调函数的入口;
从被调用函数返回调用函数之前:
- 保存被调函数的计算结果;
- 释放被调函数的数据区;
- 依照被调函数保存的返回地址将控制转移到调用函数;
当遇到嵌套调用,后调用先返回,符合栈的特点
每次调用一个函数,就在栈顶分配一个存储区
每次退出一个函数,就释放它的存储区
所以正在运行的函数的数据区必须放在栈顶
递归算法的效率
1.时间复杂度
Fibonacci 数列和 Hanoi 塔问题:O(2^n)
2.空间复杂度
阶乘间题、 Fibonacci 数列问题、 Hanoi 塔问题的递归算法的空间复杂度均为 O(n)
代码实现
for循环实现:
#include<iostream>
using namespace std;
void multiplicate()
{
int i, j,m;
for (i = 1; i <= 9; i++)
{
for (j = 1; j <= i; j++)
{
m = i * j;
cout << j<< "*" << i << "=" << m << "\t";
}
cout << endl;
}
}
int main()
{
multiplicate();
return 0;
}
递归调用
#include<iostream>
using namespace std;
void multiplicate(int i)
{
if (i == 10)
{
return;
}
else
{
for (int j = 1; j <= i; j++)
{
cout << j << "*" << i << "=" <<i*j<< "\t";
}
cout << "\n";
i++;
multiplicate(i);
}
}
int main()
{
multiplicate(1);
return 0;
}