递归就是函数调用自己,来解决子问题,经过子问题的解构造本问题的解。node
递归能够用于简化程序,让程序结构明了。。函数
调用者与被调用者之间有如下的四种数据传递关系:spa
1>没有任何数据传递指针
e.g. 打印链表code
void PrintList(ListNode const *list) { if(list == NULL) return; //exit cout << list->val << " "; PrintList(list->next); }
2> 调用者 <= === 被调用者blog
这是咱们一般习惯的数据传递(经过解决子问题,来解决本问题)递归
e.g. 计算阶乘ip
int f(int n) { if(n == 0 || n == 1) return 1; return n * f(n-1); }
3> 调用者 = ===> 被调用者it
其实咱们从小学的数的加法运算就能够认为是这种状况。class
115 + 126 = 241
低位运算结果(5+6=11)有进位,须要传递给被调用者
4> 调用者 <= ===> 被调用者
这个数据传递存在于那些子问题与本问题有相互的数据依赖性的时候。
给个例子,就会比较明了。
e.g. 用两个单链表表示两个非负整数,每一个节点表示一个十进制位,整数反向存放。
(7->1->6->NULL)表示 617
(5->9->2->NULL)表示295
计算它们的和:结果是912,要求返回一个单链表表示和
分析:
低位数据相加可能产生进位,所以存在 调用者 ====> 被调用者 的数据传递
子问题必须返回链表的头节点指针,拼到当前和的后面, 所以存在 被调用者 ====> 调用者 的数据传递
Note: 要考虑两个链表长度不一样等状况。
ListNode* SumOfListRecur(ListNode *lhs, ListNode *rhs, int flag)//flag表示进位 { int n(0); ListNode *sum(NULL), *end(NULL), *node(NULL); if(lhs == NULL && rhs == NULL && flag == 0)//exit return NULL; assert(lhs != NULL || rhs != NULL || flag != 0); n = flag; if(lhs) n += lhs->val; if(rhs) n += rhs->val; flag = n/10; n %= 10; node = new ListNode(n); sum = SumOfListRecur(lhs?lhs->next:NULL, rhs?rhs->next:NULL, flag); assert(node != NULL); node->next = sum; return node; }