遞歸函數思惟

其實,不少數據結構的題都很適合用遞歸算法來解:如鏈表,如樹,還有一些查找也很是適合遞歸,如二分查找,如歸併,如堆查找。算法

可是遞歸函數很差寫啊,一點小漏洞,都會讓你改起來痛苦的不行不行的。其實理解一下,遞歸函數就是同一個模子,給不一樣的東西作操做。數據結構

一個含直接或間接調用本函數語句的函數被稱之爲遞歸函數,在上面的例子中可以看出,它必須知足如下兩個條件:
1) 在每一次調用本身時,必須是(在某種意義上)更接近於解;
2) 必須有一個終止處理或計算的準則。

  對於(1)個人理解就是,本身調用本身的時候,參數要變,這個參數的改變,讓這次操做更接近底層,一直到底層後,會有終點返回,而後一層層返回。函數

來點題吧,乾巴巴說沒意思。spa

1.兩個有序鏈表的合併:code

紅色部分就是以上所說的,出口處理,以及參數變化。blog

ListNode* Merge(ListNode* L1, ListNode*L2)  
{
    if(L1 == NULL)
        return L1;
    if(L2 == NULL)
        return L2;
    ListNode* newhead = NULL;

    if(L1->value<L2->value)
    {
        newhead = L1;
        newhead->next = Merge(L1->next,L2);
    }
    else
    {
        newhead = L2;
        newhead->next = Merge(L1,L2->next);
    }
    
    return newhead;
}

2.二叉樹的反轉遞歸

 

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};*/
class Solution {
public:
    void Mirror(TreeNode *pRoot) {
        if(pRoot==NULL)
            return;
        if(pRoot->left==NULL&&pRoot->right==NULL)
        {
            return;
        }
        if(pRoot->left&&pRoot->right)
        {
            TreeNode* tmp = pRoot->right;
            pRoot->right = pRoot->left;
            pRoot->left = tmp;

        }
        else if(pRoot->left&&!pRoot->right)
        {
            pRoot->right = pRoot->left;
            pRoot->left = NULL;
        }

        else if(pRoot->right&&!pRoot->left)
        {
            pRoot->left = pRoot->right;
            pRoot->right = NULL;
        }
        Mirror(pRoot->right);
        Mirror(pRoot->left);
    }
};
相關文章
相關標籤/搜索