【刷算法】翻轉二叉樹的遞歸和非遞歸解法

題目形貌

操縱給定的二叉樹,將其變翻轉為源二叉樹的鏡像。

輸入形貌:

        1                    1
       / \                  / \
      2   3    ——————>     3   2
     / \ / \              / \ / \
    4  5 6  7            7  6 5  4

解題思緒

遞歸版本
起首,對數據結構比較相識的話會想到用遞返來處理。
所謂遞歸,在計算機科學中是指一種經由歷程反覆將題目剖析為同類的子題目而處理題目的要領(來自維基百科)。這個詮釋照樣比較教條的,關於工程師來講,起首要思索:

  1. 剖析題目后的子題目是什麼,也就是反覆的那一部份是什麼?
  2. 什麼時候終了反覆?即停止前提是什麼

回到翻轉二叉樹的題目,我們梳理一遍全部翻轉歷程:

root最先,交流root的left元素和root.right元素
root.left最先,交流root.left.left元素和root.left.right元素
root.right最先,交流root.right.left元素和root.right.right元素
...
...

能夠看出來反覆的部份是:交流X元素的left和right元素,用偽代碼示意為:

temp = X.left;
X.left = X.right;
X.right = temp;

那末停止前提是什麼呢?很顯然是當元素為null時,它就談不上去交流擺布子元素了,所以X=null時停止遞歸。
此時代碼就很好寫了:

function TreeNode(x) {
    this.val = x;
    this.left = null;
    this.right = null;
} 
function Mirror(root){
    // 停止前提
    if(root === null)
        return;
    // 反覆操縱的部份
    var temp = root.left;
    root.left = root.right;
    root.right = temp;
    //分別再對擺布子節點舉行一樣的操縱
    Mirror(root.left);
    Mirror(root.right);
}

非遞歸版本
非遞歸版本能夠從樹的條理遍歷上找到靈感,不過就是根據層來遍歷樹的節點,且一邊遍歷一邊交流當前節點的擺布子節點,直到遍歷終了就OK

function TreeNode(x) {
    this.val = x;
    this.left = null;
    this.right = null;
} 
function Mirror(root){
    if(root === null)
        return;
    var queue = [];// 行列來輔佐遍歷樹
    queue.push(root);

    while(queue.length !== 0) {
        var cur = queue.shift();// 彈出行列頭的元素,交流它的擺布子節點
        if(cur !== null) {
            var temp = cur.left;
            cur.left = cur.right;
            cur.right = temp;
        
            queue.push(cur.left)// 左子節點入隊
            queue.push(cur.right);// 右子節點入隊
        }  
    }    
}



    原文作者:亞古
    原文地址: https://segmentfault.com/a/1190000015305074
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞