1. 程式人生 > 其它 >【劍指offer較難部分21】按之字形順序列印二叉樹(java)

【劍指offer較難部分21】按之字形順序列印二叉樹(java)

技術標籤:劍指offer(java)佇列二叉樹queuejava面試

題目描述

請實現一個函式按照之字形列印二叉樹,即第一行按照從左到右的順序列印,第二層按照從右至左的順序列印,第三行按照從左到右的順序列印,其他行以此類推。
在這裡插入圖片描述

分析

一、佇列
從題目中可以得出兩個資訊,一個是逐行列印,那麼就用層次遍歷,另一個由於是層次遍歷,那麼最先想到的就是佇列。流程層次遍歷佇列流程就是先根節點入隊,再只要佇列不為空,就獲取佇列大小,訓練進行出隊,出隊一個佇列size就減1,size==0時,某一行就出隊完畢。在層次遍歷上加上ArrayList,並且設定一個flag,控制是從左往右還是從右往左。這是我看到這題思路。

實現程式碼如下:

import java.util.ArrayList;
import java.util.Queue;
import java.util.LinkedList;
public class Solution {
    public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
        //按行列印,即層次遍歷,先左到右,再從右到左,可以設定一個flag
        ArrayList<ArrayList<Integer>> list = new ArrayList
<>(); if(pRoot == null){ return list; } boolean flag = true; Queue<TreeNode> queue = new LinkedList<>(); queue.offer(pRoot); while(!queue.isEmpty()){ int count = queue.size();//每一行結點個數 ArrayList<Integer>
list_in = new ArrayList<>(); while(count > 0){ TreeNode cur = queue.poll();//出隊 count--; if(flag == true){ list_in.add(cur.val);//從左到右 }else{ list_in.add(0,cur.val);//從右到左,即在index=0位置插入元素,之前元素往後移 } if(cur.left != null){ queue.offer(cur.left); } if(cur.right != null){ queue.offer(cur.right); } } flag = !flag; list.add(list_in); } return list; } }

在這裡插入圖片描述

二、兩個棧
用兩個棧解決是看到網上很多都用這種方法,就是利用棧的先進後出特性,可以實現從左到右,再從右到左。一個棧add一行後,又會到另一個棧再add一行。直到兩個棧都為空,就執行結束。

import java.util.ArrayList;
import java.util.Stack;

public class Solution {
    public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
        ArrayList<ArrayList<Integer>> res = new ArrayList<>();
        if(pRoot==null)
            return res;
        Stack<TreeNode> s1 = new Stack<>();
        Stack<TreeNode> s2 = new Stack<>();
        s1.push(pRoot);
        TreeNode cur;
        while(!s1.isEmpty() || !s2.isEmpty()){
            ArrayList<Integer> list_in = new ArrayList<>();
            if(!s1.isEmpty()){
                while(!s1.isEmpty()){
                    cur = s1.pop();
                    list_in.add(cur.val);
                    if(cur.left != null)
                        s2.push(cur.left);
                    if(cur.right != null)
                        s2.push(cur.right);
                }
                res.add(list_in);
            }
            else{
                while(!s2.isEmpty()){
                    cur = s2.pop();
                    list_in.add(cur.val);
                    if(cur.right != null)
                        s1.push(cur.right);
                    if(cur.left != null)
                        s1.push(cur.left);
                }
                res.add(list_in);
            }
        }
        return res;
    }
}

在這裡插入圖片描述
個人覺得還是用佇列簡單