关于迭代和递归的思考
2015-08-13 23:08
330 查看
迭代和递归必然能相互转化。它们都需要借助栈,递归的栈是保存函数和变量的递归栈,而迭代的栈需要程序员手动声明。
有些情况下,迭代比递归更节省复杂度,但是递归在任何情况下都和迭代的复杂度相同。在不需要栈的迭代中,如果转换为递归,则白白浪费了递归栈:比如遍历单链表,如果改为递归算法,则最深层递归跳出后(即访问最后一个节点),嵌套该层的递归层没有进行任何后续操作就跳出了,以此类推,知道最外层递归层跳出。因此最内层递归技术后,实际上所有有用的操作都结束了,剩下的唯一工作就是不停地跳出递归层,因此递归栈没有任何作用,牺牲了0(n)的空间复杂度。
而如果递归层跳出后,嵌套层需要做某些操作才能再次跳出的递归算法,则转换为迭代算法时,必须使用栈。因为迭代算法的游标移动时,原先的游标指向的数据到该层迭代的内部迭代结束后依然有用,因此不能抛弃,必须放入栈中,由后进先出的原则读取。
我们可以将不需要借助栈的迭代称之为“线性迭代”,而需要借助栈的迭代成为“非线性迭代”。所有编程语言的递归算法其实都是内部对迭代的封装,因为计算的内存和运算方式是线性的。
有些情况下,迭代比递归更节省复杂度,但是递归在任何情况下都和迭代的复杂度相同。在不需要栈的迭代中,如果转换为递归,则白白浪费了递归栈:比如遍历单链表,如果改为递归算法,则最深层递归跳出后(即访问最后一个节点),嵌套该层的递归层没有进行任何后续操作就跳出了,以此类推,知道最外层递归层跳出。因此最内层递归技术后,实际上所有有用的操作都结束了,剩下的唯一工作就是不停地跳出递归层,因此递归栈没有任何作用,牺牲了0(n)的空间复杂度。
而如果递归层跳出后,嵌套层需要做某些操作才能再次跳出的递归算法,则转换为迭代算法时,必须使用栈。因为迭代算法的游标移动时,原先的游标指向的数据到该层迭代的内部迭代结束后依然有用,因此不能抛弃,必须放入栈中,由后进先出的原则读取。
我们可以将不需要借助栈的迭代称之为“线性迭代”,而需要借助栈的迭代成为“非线性迭代”。所有编程语言的递归算法其实都是内部对迭代的封装,因为计算的内存和运算方式是线性的。
相关文章推荐
- 循环报数
- iOS设计模式---命令模式
- 自定义 URL Scheme 完全指南
- opencv特征提取
- swift-08-使用键值对儿统计字符在字符串中出现的次数
- iOS开发篇——OC之面向对象的三大特征
- swift-08-使用键值对儿统计字符在字符串中出现的次数
- 黑马程序员———面向对象之包、访问修饰符、内部类
- scala 选择排序 冒泡排序
- 使用ViewPager实现可以自动切换的广告控件
- 非递归排序(冒泡、选择、插入、希尔)
- CSS学习总结
- swift-07-使用for-in 遍历数组
- swift-08-元组分解和数组
- (一)XML简介
- swift-07-使用for-in 遍历数组
- swift-08-元组分解和数组
- cocos2dx 做test遇到一个问题,记录下来
- ZOJ 3692
- 32位和64位系统区别及int字节数