Python data structures and algorithms (4.2) - recursive visualization

0. Learning Objectives

A recursive function is a function that calls itself directly or indirectly through a series of statements. Recursion plays a pivotal role in programming, and in many cases, recursion can be used to solve problems elegantly. Although recursion can be used to solve some difficult problems quickly, recursion is difficult to master due to its abstraction. In order to better understand the idea behind recursive functions, this section mainly uses visualization to understand the execution steps of recursive functions.
Through the study of this section, you should master the following:

  • Improve your understanding of recursion
  • Use visualization to understand the idea behind recursive functions

1 recursive call

Although recursion can quickly solve some difficult problems, recursion is difficult to master due to its abstraction. Although the recursive example has been explained in "Recursion Fundamentals" , and the recursive calling process has been briefly understood, it lacks specific knowledge. This section provides a more in-depth explanation of recursive calls.
When a recursive function executes, each recursive call creates a new copy of the function in memory, and once the function call ends, some data is returned and this copy is removed from memory. Often the recursive approach results in a solution that looks neat and simple, but understanding and tracking the execution of the function is more complicated. For a better understanding, consider the following simple example of finding the Fibonacci sequence:

def fibo(n):
    if n == 0:
        return 1
    else:
        return n * fibo(n - 1)
def main():
    number = 4
    result = fibo(number)
    print(result)
if __name__ == "__main__":
    main()

When the program runs to line 10. The first time a fibo()function is fibo()called, a new active record is created for the function call, and there are 3 active records on the runtime stack at this time. The Pythoninterpreter jumps to line 2, which npoints to the number 4, as shown in the figure below. nis not equal to 0, so jumps to line 5, which contains fibo()a function call to , which creates another active record on the runtime stack. Repeat the above process until n=0.
Note that each recursive function call has na . Active Record saves all local variables and parameters within the scope of the function. Every time a function is called, a new active record is created and a new copy of the local variables is stored in the active record. The calling sequence of the program running process is shown in the following figure:

runtime stack

When the function executes n=0to , the fibo()function returns its first value, which returns 1 to the previous function call. As shown in the figure below, the active record of the function call n=0when (indicated by graying out the active record in the figure). When the function returns, the active record space is reclaimed for later use. The shadow object 0 on the heap is also reclaimed by the garbage collector because there are no more references to it.

runtime stack

After the first fibo()function return, the Pythoninterpreter returns to line 5 in the previous function call, which also contains a returnstatement , so the function returns to line 5 again with a return value of 1. Again, the function returns again, but this time with a value of 2. Follow the above process until the fibo()function returns to main()line 8 of the function, as shown in the following figure:

runtime stack

Finally, the program prints the execution result, returns from the main()function returns from moduleand terminates after line 11. As you can see from the above example, each recursive call to the fibo()function creates its own copy of the variable. Each time the function is called, local variables and parameters are copied to the corresponding active record. When the function call returns, the corresponding active record is popped from the runtime stack. This is how recursive functions perform.

2 Recursive visualization

This section will use turtlethe library 's recursive drawing patterns to improve your understanding of recursive processes.

2.1 Introduction to turtle library

turtleThe library belongs to the standard library of python, which is usually used to draw patterns. You can use this library to create a small turtle ( turtle) to move on the canvas. When the small turtle crawls, it will draw lines on the canvas, and when the current tail is raised, and No drawing will take place.

Next, we'll cover some basic turtleplotting functions:

  • turtle.penup(): turtle raises its tail, and subsequent movements are not drawn on the graph
  • turtle.pendown(): turtle puts down its tail, starts crawling, and then draws its trajectory on the map
  • turtle.pensize(width): used to change the width of the brush
  • turtle.pencolor(color): used to change the brush color
  • turtle.forward(distance): move forward distance
  • turtle.back(distance): move backward by distance

2.1 Recursive drawing

First, learn about the library draw()by turtlefunction. The basic situation of this recursive function is - the length of the line to be drawn is distancereduced to than 0, let the little turtle draw distancea unit distance forward, and then Turn left 30 degrees; recursive case - call draw()function .

# 导入 turtle 库
import turtle
# 创建小乌龟对象
my_turtle = turtle.Turtle()
# 创建用户绘制图案的窗口
window = my_turtle.getscreen()

def draw(turtle, distance):
    if distance > 0:
        # 小乌龟向前绘制 distance 个单位距离
        turtle.forward(distance)
        # 然后左转 30 度
        turtle.left(30)
        draw(turtle, distance-6)
draw(my_turtle, 200)
window.exitonclick()

Next, we use the turtlemodule draw the fractal tree. Fractal tree and recursion have many things in common. It is a concept in mathematics. No matter how many times you zoom in to observe a fractal graph, you can always see the same basic shape.
If we define a tree to contain left-growing subtrees and right-growing subtrees, we can get a fractal tree according to the idea of ​​recursion:

import turtle
def tree(branch, turtle):
    if branch > 5:
        turtle.forward(branch)
        turtle.right(20)
        tree(branch-15, turtle)
        turtle.left(40)
        tree(branch-10, turtle)
        turtle.right(20)
        turtle.backward(branch)
my_turtle = turtle.Turtle()
window = my_turtle.getscreen()
my_turtle.left(90)
my_turtle.up()
my_turtle.backward(300)
my_turtle.down()
tree(110, my_turtle)
window.exitonclick()

Related Links

recursive basic concepts

Guess you like

Origin blog.csdn.net/LOVEmy134611/article/details/121198595