标签:
前言:
有很多复杂算法都包含了递归算法,特别是关于树形数据结构遍历的情景,所以正确深入理解递归算法是很有必要的。
一、递归函数的基本概念
递归函数机制理解:调用函数的静态和动态机制理解:调用函数和被调用函数虽然是同一个静态代码,但是运行时被函数运行的栈空间独立于调用函数的栈空间,调用点不同,函数状态栈地址也不同,所以运行时调用函数和被调用函数在代码副本还是数据副本上都是完全不同的,只有通过返回值和调用点进行联系。
递归的调用形式:直接递归调用F1->F1,间接递归F1->F2->F1,很多情况下是直接递归调用。
递归函数优劣点:递归函数比较消耗栈资源,实现简单(内部调用逻辑却比较复杂),但是效率没有非递归版本效率高。
二、递归函数内部调用逻辑理解:
理解层次1:
1.递归函数需要一个终止条件。
2.递归函数到终止条件,会沿路出栈对称返回。
理解层次2:
1.递归函数就是函数调用和被调用的压栈关系,只有找到都会递归调用,所以递归遍历都是深度遍历。
2.递归函数的终止条件就是在不断的递归调用下最后会发生不再调用递归函数的情况,可以是if判断也可以是for/while判断。
3.一般递归是为了遍历或者查找,如果查找条件(非终止条件)在递归遍历前面,那么不用全部遍历找到就会返回;如果查找条件(非终止条件)在递归遍历后面,那么需要全部遍历才会返回。
三、一个遍历3ds Max导出节点的递归算法的模拟示例
RecursiveFunc.h文件:
#ifndef RECURSIVEFUNC_H_ #define RECURSIVEFUNC_H_ #include <string> #include <list> using namespace std; typedef struct tagMaxTreeNode { int m_nIndex; string m_strName; tagMaxTreeNode(int nIndex, const string& strName) { m_nIndex = nIndex; m_strName = strName; } void AddChild(tagMaxTreeNode* pChild) { m_listChild.push_back(pChild); } list<tagMaxTreeNode*> m_listChild; }MaxTreeNode; template <class T> class MaxTree { public: MaxTree() { m_root = NULL; } ~MaxTree() { } void AddNode(T *pParent, T *pChild) { if( pParent == NULL ) { m_root = pParent; return; } else { pParent->AddChild(pChild); } } void BrowseF( T* pNode) { printf("BrowseF:Recursive Call nIndex: %d\n", pNode->m_nIndex); if( pNode->m_nIndex < 10 ) { printf("BrowseF:Condition Hit nIndex: %d\n", pNode->m_nIndex); return; } list<T*>::iterator itrChild = pNode->m_listChild.begin(); for(; itrChild != pNode->m_listChild.end(); ++itrChild) { BrowseF( *itrChild); } } void BrowseL( T* pNode) { printf("BrowseF:Recursive Call nIndex: %d\n", pNode->m_nIndex); list<T*>::iterator itrChild = pNode->m_listChild.begin(); for(; itrChild != pNode->m_listChild.end(); ++itrChild) { BrowseF( *itrChild); } if( pNode->m_nIndex < 10 ) { printf("BrowseF:Condition Hit nIndex: %d\n", pNode->m_nIndex); return; } } private: T* m_root; }; #endif
main1.cpp文件:
#include "stdafx.h" #include "RecursiveFunc.h" int _tmain(int argc, _TCHAR* argv[]) { MaxTreeNode node1(1, "node1"); MaxTreeNode node2(10, "node2"); MaxTreeNode node3(100, "node3"); MaxTreeNode node4(1000, "node4"); MaxTreeNode node5(10000, "node5"); /*MaxTreeNode node1(1000, "node1"); MaxTreeNode node2(1000, "node2"); MaxTreeNode node3(100, "node3"); MaxTreeNode node4(100, "node4"); MaxTreeNode node5(1, "node5");*/ MaxTree<MaxTreeNode> TestTree; TestTree.AddNode(NULL, &node1); TestTree.AddNode(&node1, &node2); TestTree.AddNode(&node1, &node3); TestTree.AddNode(&node2, &node4); TestTree.AddNode(&node3, &node5); printf("------------TestTree.BrowseF(&node1);-------\n"); TestTree.BrowseF(&node1); printf("------------TestTree.BrowseL(&node1);-------\n"); TestTree.BrowseL(&node1); return 0; }
输出结果:
main2.cpp:
#include "stdafx.h" #include "RecursiveFunc.h" int _tmain(int argc, _TCHAR* argv[]) { /*MaxTreeNode node1(1, "node1"); MaxTreeNode node2(10, "node2"); MaxTreeNode node3(100, "node3"); MaxTreeNode node4(1000, "node4"); MaxTreeNode node5(10000, "node5");*/ MaxTreeNode node1(10000, "node1"); MaxTreeNode node2(1000, "node2"); MaxTreeNode node3(100, "node3"); MaxTreeNode node4(100, "node4"); MaxTreeNode node5(1, "node5"); MaxTree<MaxTreeNode> TestTree; TestTree.AddNode(NULL, &node1); TestTree.AddNode(&node1, &node2); TestTree.AddNode(&node1, &node3); TestTree.AddNode(&node2, &node4); TestTree.AddNode(&node3, &node5); printf("------------TestTree.BrowseF(&node1);-------\n"); TestTree.BrowseF(&node1); printf("------------TestTree.BrowseL(&node1);-------\n"); TestTree.BrowseL(&node1); return 0; }输出结果:
标签:
原文地址:http://blog.csdn.net/blues1021/article/details/45330783