12:36 2012-9-25
遍歷網頁各框架,用到的正是遞歸調用.不過這個遞歸的樣式特別些,因為以前沒有見過,所以感到挺新鮮的,我叫它雙函數遞歸.
以前的就是自己調用自己而已:
void EnumCount(int i)
{
if(i==0) return;
EnumCount(i--);
}
新的:
void Enumframe(DOM)
{
frame_count =DOM->get_frames();
if(frame_count == 0) return;
for_each(frames)
Enumform(GetDom());
}
Enumform(DOM) //入口
{
Enumframe(DOM);
...//處理各種元素
}
出現遞歸了,往往說明要處理的數據結構是個樹形結構.
比如遍歷二叉樹:
struct node
{
node* left;
node* right;
}
void enum_tree(node)
{
if(node == NULL) return;
enum_tree(node->left);
enum_tree(node->right);
}
對於DOM樹,子節點是多變的,不會像2,4,8叉樹那樣工整了,不過它更符合復雜的現實.
仿寫一個:
#include <stdio.h>#include <string.h>
struct node
{char name[10];
int count; //子節點個數node* pNodeArray[]; //子節點指針數組
};void enum_node(node* pNode);
void enum_apple(node* pNode)
{enum_node(pNode);printf(pNode->name);printf("\n");
}void enum_node(node* pNode)
{int NodeCount =pNode->count;
if(NodeCount == 0) return;for(int i =0; i<NodeCount; i++)enum_apple(pNode->pNodeArray[i]);}void enum_tree()
{//創建樹
node* root =new node;
root->count =2;strcpy(root->name, "ROOT");
root->pNodeArray[0] =new node;
root->pNodeArray[0]->count =2;strcpy(root->pNodeArray[0]->name, "LEFT: ");
root->pNodeArray[0]->pNodeArray[0] = new node;
root->pNodeArray[0]->pNodeArray[0]->count =0;strcpy(root->pNodeArray[0]->pNodeArray[0]->name, "LEFT_1: ");
root->pNodeArray[0]->pNodeArray[1] = new node;
root->pNodeArray[0]->pNodeArray[1]->count =0;strcpy(root->pNodeArray[0]->pNodeArray[1]->name, "LEFT_2: ");
root->pNodeArray[1] =new node;
root->pNodeArray[1]->count =4;strcpy(root->pNodeArray[1]->name, "RIGHT: ");
root->pNodeArray[1]->pNodeArray[0] = new node;
root->pNodeArray[1]->pNodeArray[0]->count =0;strcpy(root->pNodeArray[1]->pNodeArray[0]->name, "RIGHT_1: ");
root->pNodeArray[1]->pNodeArray[1] = new node;
root->pNodeArray[1]->pNodeArray[1]->count =0;strcpy(root->pNodeArray[1]->pNodeArray[1]->name, "RIGHT_2: ");
root->pNodeArray[1]->pNodeArray[2] = new node;
root->pNodeArray[1]->pNodeArray[2]->count =0;strcpy(root->pNodeArray[1]->pNodeArray[2]->name, "RIGHT_3: ");
root->pNodeArray[1]->pNodeArray[3] = new node;
root->pNodeArray[1]->pNodeArray[3]->count =0;strcpy(root->pNodeArray[1]->pNodeArray[3]->name, "RIGHT_4: ");
//遍歷樹
enum_apple(root);}void main()
{enum_tree();}
結論:
它的遍歷方向是,先順序遍歷完子節點,在遍歷上一層節點.
技巧:
遞歸的條件出口,寫在尾函數的最前面.