1. 程式人生 > >二叉樹遍歷LeetCode#144 #94 #145 (前中後序遍歷)

二叉樹遍歷LeetCode#144 #94 #145 (前中後序遍歷)

  • 題目:二叉樹的前序遍歷(遞迴以及非遞迴方法)
  • 難度:Medium
  • 思路:遞迴很簡單,非遞迴需要藉助棧來實現
  • 程式碼:
    遞迴程式碼
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    //遞迴方法
    public List<Integer> preorderTraversal
(TreeNode root) { List<Integer> result = new ArrayList<Integer>(); if(root == null){ return result; } recursion(root,result); return result; } public void recursion(TreeNode node, List<Integer> list){ if(node == null
){ return; }else{ //先遞迴左子樹,再遞迴右子樹 list.add(node.val); recursion(node.left, list); recursion(node.right, list); } } }

非遞迴程式碼

public class Solution {
    //遞迴方法
    public List<Integer> preorderTraversal(TreeNode root) {
        List
<Integer> result = new ArrayList<Integer>(); if(root == null){ return result; } //利用雙向連結串列做棧使用 LinkedList<TreeNode> stack = new LinkedList<>(); stack.push(root); while(!stack.isEmpty()){ TreeNode node = stack.pop(); result.add(node.val); //注意:將右子樹先壓入棧(先序遍歷的順序是先跟節點,再左子樹,再右子樹) if(node.right != null){ stack.push(node.right); } if(node.left != null){ stack.push(node.left); } } return result; } }
  • 題目:二叉樹的後序遍歷(遞迴與非遞迴方式)
  • 難度:Medium
  • 思路:後序遍歷的遞迴方式與前序相似,只需要將跟節點的訪問調整到左右子樹訪問之後;而非遞迴
  • 程式碼:
    遞迴方法
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        if(root == null){
            return result;
        }
        recursion(root, result);
        return result;
    }

    public void recursion(TreeNode node, List<Integer> list){
        if(node == null){
            return;
        }else{
            recursion(node.left, list);
            recursion(node.right, list);
            list.add(node.val);
        }
    }
}

非遞迴方法

public class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        if(root == null){
            return result;
        }
        LinkedList<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        TreeNode curr = null;
        TreeNode pre = null;
        while(!queue.isEmpty()){
            curr = queue.peekLast();
            //1.當前節點為葉子節點時,該節點需要加入result列表
            //2.上一個訪問的節點是當前節點的左孩子或者右孩子時,說明該節點的左右子樹節點都已經被訪問過,該節點也被加入result列表
            //對於第2點,可能存在疑問:如果當前節點有兩個孩子,應該需要判斷它兩個孩子都被訪問呀?,事實是,我們在入佇列的時候是右孩子先入佇列,然後左孩子再入佇列。curr節點的右孩子等於pre的時候,說明curr節點的左孩子已經被訪問了或者curr節點沒有左孩子;curr節點的左孩子等於pre的時候,說明curr節點只有左孩子
            if((curr.left == null && curr.right == null) || 
                (pre != null &&(curr.left == pre || curr.right == pre))){
                result.add(curr.val);
                pre = queue.pollLast();
            }else{
                if(curr.right != null){
                    queue.offer(curr.right);
                }
                if(curr.left != null){
                    queue.offer(curr.left);
                }
            }
        }
        return result;
    }
}
  • 題目:中序遍歷二叉樹(遞迴和非遞迴)
  • 難度:Medium
  • 思路:遞迴方式遍歷與前後序基本一樣,只是改變訪問根節點的位置;非遞迴方式,我覺得比較難,主要是想統一三種遍歷的程式碼,對中序遍歷來講,這裡使用到一個trick就是將curr.left將入棧之後,就把curr.left設定為null
  • 程式碼:
    遞迴
public class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        if(root == null){
            return result;
        }
        recursion(root, result);
        return result;
    }
    public void recursion(TreeNode node, List<Integer> list){
        if(node == null){
            return;
        }else{
            recursion(node.left, list);
            list.add(node.val);
            recursion(node.right, list);
        }
    }

}

非遞迴

public class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        if(root == null){
            return result;
        }
        LinkedList<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        TreeNode curr = null;
        while(!queue.isEmpty()){
            curr = queue.peekLast();
            System.out.println("進入while迴圈");
            if(curr.left != null){
                queue.offer(curr.left);
                curr.left = null;//這個trick非常重要,不然就會死迴圈
            }else{
                result.add(curr.val);
                curr = queue.pollLast();
                if(curr.right != null){
                    queue.offer(curr.right);
                }
            }

        }
        return result;
    }

}

相關推薦

LeetCode#144 #94 #145

題目:二叉樹的前序遍歷(遞迴以及非遞迴方法) 難度:Medium 思路:遞迴很簡單,非遞迴需要藉助棧來實現 程式碼: 遞迴程式碼 /** * Definition for a binary

Leetcode:的層非遞迴版

102. 二叉樹的層次遍歷 給定一個二叉樹,返回其按層次遍歷的節點值。 (即逐層地,從左到右訪問所有節點)。 例如: 給定二叉樹: [3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7 返回

遞迴和非遞迴版本

各位讀者週末愉快呀,今天我想來說說一道很常見的面試題目 —— 關於二叉樹前中後序遍歷的實現。本文將以遞迴和非遞迴方式實現這 3 種遍歷方式,程式碼都比較短,可以放心食用。 先簡單說明一下這 3 種遍歷方式有什麼不同 —— 對於每種遍歷,樹中每個結點都需要經過 3 次(對於葉結點,其左右子樹視為空子樹),但前

遞迴+非遞迴

/** * 二叉樹節點類 * @author wj * */ class TreeNode{ int value; TreeNode left_Node; TreeNode right_Node; public TreeNode(int value) { this.value

基礎操作 ,,求高度,搜尋排序Java實現 程式碼集合

首先,定義一個樹類Tree.java public class Tree { public TreeNode root; } 定義樹節點類TreeNode.java public class TreeNode { public TreeNode(int

(遞迴&非遞迴)

中序遞迴: class Solution { public: vector<int> res; vector<int> inorderTraversal(Tre

javascript生成, 以及其

序言 最近看了些面試題, 發現大多數都會問一個問題就是JavaScript生成二叉樹, 本來想偷懶百度看看算了, 可是發現好多網站部落格的程式碼都是一樣的, 並且生成的還是平衡二叉樹………. 如果我不輸入數字你給我生成一個試試. so, 看起來只能自己搞一下了. 百度百科–平衡二

(遞迴&非遞迴)

中序遞迴: class Solution { public: vector<int> res; vector<int> inorderTraversal(TreeNode * root) { inorder(root);

的建立及和層次

樹是N個結點的有限集合,N=0時稱為空樹,任意一顆非空樹滿足以下條件: 有且只有一個特定的稱為根的結點 當N>1時,其他結點可分為m個互不相交的悠閒集合,其中每個集合本身又是一個棵樹,並稱為根節點的子樹 樹的定義是遞迴的,是一種遞迴的資料結構,樹作為一

的建立及其

1 //二叉樹儲存結構: 2 struct node 3 { 4 Int data; 5 node *lchild; 6 node *rchild; 7 }; 8 9 //二叉樹在建樹前根節點不存在: 10 Node *root = NULL; 11 12

javascript實現排序,,最大最小值特定值查詢以及刪除節點

 函式執行時,會產生一個棧用來存放資料,當遍歷到目的節點時,操作結束以後,就會自動執行出棧操作,所以每次執行完畢指標都會自動跳回根節點。可以在開發者模式裡打斷點看到全過程。 <!DOCTYPE html> <html> <head> <me

,, (遞迴 && 非遞迴的棧 && 非遞迴非棧的線索)

先簡單介紹下線索二叉樹,線索二叉樹不需要額外的空間便可以O(n)遍歷二叉樹,它充分利用了節點的空指標,若當前結點的左孩子不為空則其左指標指向左孩子結點,否則指向當前節點的前驅;若當前結點的右孩子不為空則其右指標指向右孩子結點,否則指向當前節點的後繼。具體看程式碼實現 前序遍

本文介紹二叉樹的前序,中序和後序遍歷,採用遞迴和非遞迴兩種方式實現。除此之外,還介紹了對二叉樹按層遍歷的方法。對樹的前中後序遍歷是深度優先搜尋的策略,因此用棧實現。對樹的按層遍歷是廣度優先搜尋,因此採用佇列實現。 樹的前序,中序和後序遍歷,都是針對父節點而言的。 二叉樹的定

非遞迴實現//

//基本資料結構 template<class T> struct BinaryTreeNode { T _data; BinaryTreeNode<T>* _left;

非遞迴實現總結 --- Java語言實現

前言 三種遍歷的遞迴寫法都很好寫,所以總結一下非遞迴寫法。 先貼一張圖複習一下三種遍歷方式就進入正文啦~ 【注:本文所有程式碼實現中樹的結點定義如下: public class Node {

的建立及

Problem Description 按照給定的擴充套件二叉樹前序遍歷序列建立相應的非空二叉樹,要求採用二叉連結串列進行儲存表示,並對其進行中序和後序遍歷,輸出中後序遍歷序列後請銷燬二叉連結串列以釋放記憶體。 Input 第一行為一個整數n,表示以下有n組資料,每組資料佔一行,為擴

的先(遞迴和非遞迴)、(遞迴和非遞迴)、(非遞迴)及層次java實現

二叉樹的先序遍歷,遞迴實現: public List<Integer> preorderTraversal(TreeNode root) { //用棧來實現 List<Integer> list = new ArrayList&l

用python實現搜尋/查詢的簡單實現及驗證判斷

基於棧的中根序深度優先遍歷判斷法(天然排序,每次比上一個值大即可)。由搜尋樹的性質推得中根序深度遍歷為一個從小到大的有序序列。所以根據這一性質事情就好辦了,只要在遍歷過程中加入與前一值得比較判斷即能達到目的(複雜度O(n),推薦演算法)。程式碼如下:def midorder(

的C++程式碼

馬上就要資料結構考試了,會考到二叉樹的遍歷演算法設計題,然後就自己總結了一個關於二叉樹的簡單演算法程式碼。 #include <iostream> #include <stdio.h> #include <stdlib.h> #inclu

遞迴建立,層次非遞迴,以及統計葉子結點個數以及的深度

下面的程式碼實現了二叉樹的先序或者後序遞迴建立,然後實現了二叉樹的非遞迴的先序中序後序遍歷,還有層次遍歷,以及統計樹的葉子結點個數和樹的深度。其中非遞迴的先中後序遍歷用到了鏈棧,層次遍歷用到了佇列。 程式設計平臺為Visual Studio 2012,語言為C,但不是純C,