【第三天】算法图解 之 递归

简介: 【第三天】算法图解 之 递归

本章包含大量伪代码,伪代码是对手头问题的简要描述,看着像代码,但更接近自然语言。介于自然语言和编程语言之间,是一种描述算法的语言。


1. 递归


* 盒子里面有盒子,而盒子里的盒子又有盒子,钥匙在某个盒子中,有什么方法能找到钥匙?


方法一:


1> 创建一个要查找的盒子堆


2> 从盒子堆中取出一个盒子,在里面找


3> 如果找到的是盒子,就将其加入盒子堆中,以便以后再查找


4> 如果找到钥匙,则大功告成


伪代码:


def look_for_key(main_box):
    pile = main_box.make_a_pile_to_look_through()
    while pile is not empty:
        box = pile.grab_a_box()
        for item in box:
            if item.is_a_box():
                pile.append(item)
            elif item.is_a_key():
                print("found  the key")


示例代码:


def lookkey(main_box):
    for box in main_box:
        for pile in box:
            if pile == "box":
                main_box.append(pile)
                print("It's a box")
            elif pile == "key":
                print("found the key")
A = [["box"],["box"],["key"],["box"]]
lookkey(A)


运行:


1. It's a box
2. It's a box
3. found the key
4. It's a box


方法二:


1> 详细检查盒子中的每样东西


2> 如果是盒子,就返回第一步


3> 如果是钥匙,就大功告成


伪代码:


def look_for_key(box):
    for item in box:
        if item.is_a_box():
            look_for_key(item)
        elif item.is_a_key():
            print("found the key")


示例代码:


def LookKey(Box):
    for item in Box:
        if type(item) == list:
            print("There's another box in here.")
            LookKey(item)
        elif type(item) == str:
            if item == "box":
                print("There is not key in the box")
                print()
            elif item == "key":
                print("found the key")
                print()
B = [["box"],"box",["key"],["box"]]
LookKey(B)


运行:


There's another box in here.
There is not key in the box
There is not key in the box
There's another box in here.
found the key
There's another box in here.
There is not key in the box


2. 基线条件和递归条件


编写递归函数时,必须告诉它何时停止递归


每个递归函数都有两部分:基线条件和递归条件


递归条件指的是函数自己调用自己,而基线条件则指的是函数不再调用自己,从而避免形成无限循环


* 倒计时函数:3……2……1


def countdown(i):
    print(i)
    countdown(i-1)


运行结果:3……2……1……0……-1……-2……


无限循环


添加基线条件


def countdown(i):
    print(i)
    if i <= 0:          # 基线条件
        return
    else:               # 递归条件
        countdown(i-1)


运行结果:3……2……1……0


3. 栈


处理待办事项清单,一叠便条要简单得多,插入的待办事项放在清单的最前面,读取待办事项时,你只读取最上面的那个,并将其删除。因此只有两种操作:压入(插入)和弹出(删除并读取)


栈是一种简单的数据结构


①调用栈


计算机在内部使用被称为调用栈的栈


下面是一个简单函数,作用是问候用户


def greet2(name):
    print("how are you," + name + "?")
def bye():
    print("ok bye!")
def greet(name):
    print("hello," + name + "!")
    greet2(name)
    print("getting ready to say bye……")
    bye()
greet("lilrain")


运行:


1. hello,lilrain!
2. how are you,lilrain?
3. getting ready to say bye……
4. ok bye!


② 递归调用栈


计算阶乘的递归函数


def fact(x):
    if x == 1:
        return 1
    else:
        return x * fact(x - 1)
print(fact(3))


运行


6


详解分析调用fact(3)时调用栈是如何变化的:


(栈顶的方框指出了当前执行到了什么地方)



每个fact调用都有自己的x变量,在一个函数调用中不能访问另一个的x变量


回归盒子堆的递归解决方法(二)


盒子堆存储在了栈中,这个栈包含未完成的函数调用,每个函数调用都包含还未检查完的盒子,无需自己跟踪盒子堆——栈替你这样做了


使用栈虽然方便,但也要付出代价:储存详尽的信息可能占用大量的内存。每个函数调用都要调用一定的内存,如果栈很高,就意味着计算机存储了大量函数调用的信息。这种情况下,有两种选择:1>重新编写代码;  2>使用尾递归


4. 小结


①递归指的是调用自己的函数


②每个递归函数都有两个条件:基线条件和递归条件


③栈有两种操作:压入和弹出


④所有函数调用都进入调用栈


⑤调用栈可能很大,这将占用大量内存

相关文章
|
2月前
|
机器学习/深度学习 算法
递归算法题练习(数的计算、带备忘录的递归、计算函数值)
递归算法题练习(数的计算、带备忘录的递归、计算函数值)
|
2月前
|
机器学习/深度学习 数据采集 监控
机器学习-特征选择:如何使用递归特征消除算法自动筛选出最优特征?
机器学习-特征选择:如何使用递归特征消除算法自动筛选出最优特征?
97 0
|
2月前
|
存储 缓存 算法
【数据结构与算法】【小白也能学的数据结构与算法】递归 分治 迭代 动态规划 无从下手?一文通!!!
【数据结构与算法】【小白也能学的数据结构与算法】递归 分治 迭代 动态规划 无从下手?一文通!!!
|
29天前
|
算法
算法系列--递归(一)--与链表有关(上)
算法系列--递归(一)--与链表有关
28 0
|
4月前
|
算法
【算法系列篇】递归、搜索和回溯(四)
【算法系列篇】递归、搜索和回溯(四)
|
1月前
|
搜索推荐 C语言 C++
【排序算法】C语言实现归并排序,包括递归和迭代两个版本
【排序算法】C语言实现归并排序,包括递归和迭代两个版本
|
1月前
|
存储 算法 搜索推荐
【数据结构与算法】归并排序(详解:递归与非递归的归并排序 | 赠:冒泡排序和选择排序)
【数据结构与算法】归并排序(详解:递归与非递归的归并排序 | 赠:冒泡排序和选择排序)
|
2月前
|
存储 编解码 自然语言处理
【软件设计师备考 专题 】深入理解数据压缩、递归和图的相关算法
【软件设计师备考 专题 】深入理解数据压缩、递归和图的相关算法
66 0
|
2月前
|
算法 Java 定位技术
【数据结构与算法】递归、回溯、八皇后 一文打尽!
【数据结构与算法】递归、回溯、八皇后 一文打尽!
|
2月前
|
存储 算法 C语言
【数据结构与算法】【约瑟夫问题】还在用递归?教你用链表秒杀约瑟夫
【数据结构与算法】【约瑟夫问题】还在用递归?教你用链表秒杀约瑟夫