黄色网址大全免费-黄色网址你懂得-黄色网址你懂的-黄色网址有那些-免费超爽视频-免费大片黄国产在线观看

專注Java教育14年 全國(guó)咨詢/投訴熱線:400-8080-105
動(dòng)力節(jié)點(diǎn)LOGO圖
始于2009,口口相傳的Java黃埔軍校
首頁(yè) hot資訊 非遞歸后序遍歷二叉樹(shù)算法

非遞歸后序遍歷二叉樹(shù)算法

更新時(shí)間:2022-09-09 09:28:51 來(lái)源:動(dòng)力節(jié)點(diǎn) 瀏覽1108次

方法1

非遞歸用棧來(lái)輔助遍歷,后序遍歷是第三次遇到該節(jié)點(diǎn)再遍歷,但是棧只能給我們提供遇到兩次的判斷方法,第一次是入棧時(shí),第二次是出棧時(shí),它們分別對(duì)應(yīng)著二叉樹(shù)的先序和中序遍歷。所以我們需要利用一些技巧來(lái)輔助我們判斷,這也是后序遍歷二叉樹(shù)比先序和中序稍微復(fù)雜一點(diǎn)的原因。

看著代碼進(jìn)行分析。

public static void postOrderTraverse(TreeNode root) {
    TreeNode p = root;
    TreeNode pre = null;
    LinkedList<TreeNode> stack = new LinkedList<>();
    while (p != null || stack.size() != 0) {
        while (p != null) {
            stack.push(p);
            p = p.left;
        }
        p = stack.pop();
        if (p.right == null) { // leaf 
            pre = p;
            System.out.println(p.val);
            p = p.right;
        } else if (p.right == pre) { // pre is p.right
            pre = p;
            System.out.println(p.val);
            p = null;
        } else {  // p.right dont traverse
            stack.push(p);
            p = p.right;
        }
    }
}

過(guò)程和前序中序基本一樣,那什么時(shí)候我們需要遍歷呢?當(dāng)這個(gè)節(jié)點(diǎn)是葉子節(jié)點(diǎn)時(shí)或當(dāng)這個(gè)節(jié)點(diǎn)的右子樹(shù)已經(jīng)遍歷完了時(shí)就可以遍歷了,否則我們?cè)俅螌⑺霔#却麓伪闅v。同時(shí)也說(shuō)明只有當(dāng)這個(gè)節(jié)點(diǎn)是葉子節(jié)點(diǎn)或者這個(gè)節(jié)點(diǎn)的右子樹(shù)已經(jīng)訪問(wèn)完了時(shí)這個(gè)節(jié)點(diǎn)才能順利出棧。

葉子節(jié)點(diǎn)判斷

葉子節(jié)點(diǎn)很好判斷,只要它的右孩子為 null 就代表它是葉子節(jié)點(diǎn),因?yàn)樽蠛⒆右欢?null,否則不會(huì)從前面那個(gè) while 中跳出。

右子樹(shù)是否遍歷完判斷

看上面代碼,我們是在順利出棧的時(shí)候進(jìn)行遍歷,而后序遍歷當(dāng)前節(jié)點(diǎn)的上一個(gè)遍歷節(jié)點(diǎn)就是它的右孩子,我們用 pre 記錄上次順利出棧的節(jié)點(diǎn),判斷如果當(dāng)前節(jié)點(diǎn)的右子節(jié)點(diǎn)就是上一個(gè)順利出棧的節(jié)點(diǎn),代表右子樹(shù)已經(jīng)遍歷完了,就遍歷當(dāng)前節(jié)點(diǎn)。

接下來(lái)還有一個(gè)問(wèn)題,前序和中序遍歷時(shí),在彈出一個(gè)節(jié)點(diǎn)時(shí)都是直接讓 p = p.right ,接著去訪問(wèn)右子樹(shù),后序遍歷有點(diǎn)不同。第一次彈出這個(gè)節(jié)點(diǎn)時(shí),和前序和中序一樣,需要接著去訪問(wèn)其右子樹(shù),使 p = p.right ;但是當(dāng)?shù)诙螐棾鲞@個(gè)節(jié)點(diǎn)時(shí),即上面判斷它的右子樹(shù)已經(jīng)訪問(wèn)完了時(shí),就不能再去訪問(wèn)右子樹(shù)了,要不就會(huì)死循環(huán)了,應(yīng)該讓 p = null,繼續(xù)出棧元素。

懂了上面上面代碼后,發(fā)現(xiàn)其實(shí)上面兩個(gè)分支可以合成一個(gè),所以最后的代碼如下。

public static void postOrderTraverse(TreeNode root) {        
    TreeNode p = root;
    TreeNode pre = null;
    LinkedList<TreeNode> stack = new LinkedList<>();
    while (p != null || stack.size() != 0) {
        while (p != null) {
            stack.push(p);
            p = p.left;
        }
        p = stack.pop();
        // left or pre is p.right
        if (p.right == null || p.right == pre) { 
            pre = p;
            System.out.println(p.val);
            p = null;
        } else {  // p.right dont traverse
            stack.push(p);
            p = p.right;
        }
    }
}

方法2 Morris方法

Morris方法和前序中序一樣,只是它的遍歷點(diǎn)不一樣,它是在每個(gè)節(jié)點(diǎn)第二次訪問(wèn)時(shí)將它的左樹(shù)的最右序列反著遍歷一遍。但是這樣會(huì)導(dǎo)致整個(gè)樹(shù)的最右序列沒(méi)有遍歷,所以最后還要加一個(gè)整個(gè)樹(shù)的最右序列遍歷。這應(yīng)該是最麻煩的二叉樹(shù)遍歷方法了。代碼如下。

public static void postOrderTraverse(TreeNode root) {
    TreeNode cur = root;
    TreeNode rightmost = null;
    while (cur != null) {
        if (cur.left != null) {
            rightmost = cur.left;
            while (rightmost.right != null && rightmost.right != cur) {
                rightmost = rightmost.right;
            }
            if (rightmost.right == null) {
                rightmost.right = cur;
                cur = cur.left;
            } else {
                rightmost.right = null;
                reverseTraverse(cur.left);
                cur = cur.right;
            }
        } else {
            cur = cur.right;
        }
    }
    reverseTraverse(root);
}
public static void reverseTraverse(TreeNode node) {
    TreeNode head = reverse(node);
    TreeNode p = head;
    while (p != null) {
        System.out.println(p.val);
        p = p.right;
    }
    reverse(head);
}
public static TreeNode reverse(TreeNode node) {
    if (node == null || node.right == null) {
        return node;
    }
    TreeNode cur = node;
    TreeNode next = node.right;
    TreeNode temp = node.right;
    cur.right = null;
    while (next != null) {
        temp = next.right;
        next.right = cur;
        cur = next;
        next = temp;
    }
    return cur;
}

 

提交申請(qǐng)后,顧問(wèn)老師會(huì)電話與您溝通安排學(xué)習(xí)

免費(fèi)課程推薦 >>
技術(shù)文檔推薦 >>
主站蜘蛛池模板: 亚洲欧美日产综合一区二区三区 | 国产日本欧美在线观看 | 波多野结衣一区二区三区 | 久久精品亚洲综合 | 亚洲日本va | 黄色片日本网站 | 日本人与物videos另类 | 99精品视频免费在线观看 | 国产亚洲欧美日韩在线看片 | 国产成人免费无庶挡视频 | 国产中文久久精品 | 成年性午夜免费视频网站不卡 | 成人短视频在线观看 | 天天摸日日摸人人看 | 91在线 | 亚洲 | 国产成人一区二区 | 国产欧美国产精品第二区 | 亚洲精品在线播放视频 | 日本aⅴ精品一区二区三区久久 | 一级做性色a爰片久久毛片免费 | 欧美日韩精品一区二区三区四区 | 一区二区三区国产 | 成人欧美 | 日韩久草视频 | 欧美日韩福利视频 | 国产偷国产偷亚洲高清在线 | 91看片淫黄大片欧美看国产片 | 成 人 黄 色 免费网 | 精品视频一区二区三区 | 成年视频网站免费观看 | 又长又深又硬又黄又猛又爽 | 高清国产在线观看 | 日韩午夜视频在线观看 | a亚洲欧美中文日韩在线v日本 | 曰皮全部过程视频免费高清 | 影音先锋最新资源网 | freexxx性欧美极品另类 | 日韩国产欧美精品综合二区 | 亚洲免费片 | 国产亚洲精品拍拍拍拍拍 | 一级一级一片免费 |