第四十五课 递归的思想与应用(下)

Posted wanmeishenghuo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第四十五课 递归的思想与应用(下)相关的知识,希望对你有一定的参考价值。

技术分享图片

 

技术分享图片

g函数返回后,f函数对应的栈中的数据没有任何变化,这就是回溯算法的核心。

 

 

技术分享图片

 

可以这样思考,先逆序打印从第二个节点开始的子表,最后再将第一个节点打印出来。

 1 #include <iostream>
 2 #include <cstring>
 3 #include "DTString.h"
 4 
 5 using namespace std;
 6 using namespace DTLib;
 7 
 8 struct Node
 9 {
10     int value;
11     Node* next;
12 };
13 
14 Node* create_list(int v, int len)  // v:数据元素从哪一个之开始。 len:长度
15 {
16     Node* ret = NULL;
17     Node* slider = NULL;
18 
19     for(int i=0; i<len; i++)
20     {
21         Node* n = new Node();
22 
23         n->value = v++;
24         n->next = NULL;
25 
26         if( slider == NULL )
27         {
28             slider = n;
29             ret = n;
30         }
31         else
32         {
33             slider->next = n;
34             slider = n;
35         }
36     }
37 
38     return ret;
39 }
40 
41 void destroy_list(Node* list)
42 {
43     while( list )
44     {
45         Node* del = list;
46 
47         list = list->next;
48 
49         delete del;
50     }
51 }
52 
53 void print_list(Node* list)
54 {
55     while( list )
56     {
57         cout << list->value << "->";
58 
59         list = list->next;
60     }
61 
62     cout << "NULL" << endl;
63 }
64 
65 
66 
67 void r_print_even(Node* list)
68 {
69     if( list != NULL)
70     {
71         r_print_even(list->next);
72 
73         if( (list->value % 2) == 0 )
74         {
75             cout << list->value << endl;
76         }
77     }
78 }
79 
80 int main()
81 {
82     Node* list = create_list(2, 5);
83 
84     print_list(list);
85 
86     r_print_even(list);
87 
88     destroy_list(list);
89 
90     return 0;
91 }

技术分享图片

 

 

 逆序打印栈的增长与退栈示意图:

技术分享图片

 

 退栈打印的过程就是回溯的过程。

 递归调用的时候只是先将参数保存在栈上,这时这个参数还没有用到,只是让指针指向了相应的节点,退栈的时候才用到。

类似于走迷宫,走到一个路口时先做个标记,这个标记暂时不用,回来的时候再用。根据标记找来时的路。

回溯的本质就是做标记,这样方便回退。

 

八皇后:

技术分享图片

技术分享图片

放皇后的时候只需要关注箭头的方向,因为其他的方向还没有放任何东西。

当我们发现某一行的任何一个位置都不能放皇后的时候,就开始要回溯了。因为,这证明了上一行放置皇后的地方是错误的。

技术分享图片

 

 当我们发现第i行的任何一个位置都不能放置皇后了,这就证明了第i-1行放置的位置是错误的。

如果发现第i-1行也没有地方可以放置皇后了,这意味着还要继续回退,退到i-2行,这就是回溯。

 

 

技术分享图片

 

 技术分享图片

理论上,每放置一个皇后要判断8个方向,但是我们从第一行开始放置皇后,有规律的放,因此,只需要考虑三个方向。

技术分享图片

如果判断一个位置的左下角对角线是否已经放置了皇后,那就在这个位置的基础上,在xy坐标上不断的减一。因此,方向数据很重要。左下角方向数据是(-1,-1)。

技术分享图片

 

 

技术分享图片

 

以上是关于第四十五课 递归的思想与应用(下)的主要内容,如果未能解决你的问题,请参考以下文章

python第四十五课——继承性之多继承

第四十四课 递归的思想与应用(中)

Golang✔️走进 Go 语言✔️ 第十五课 递归 & 接口

Golang✔️走进 Go 语言✔️ 第十五课 递归 & 接口

第四十五章

第四十五篇UITableViewCell高度计算