二叉樹的按層列印與ZigZag列印

2022-09-19 18:03:12 字數 2464 閱讀 9342

題目:二叉樹的按層列印與zigzag列印

《程式設計師**面試指南》第39題 p132 難度:尉

★★☆☆

按層列印原本是非常基礎的內容,對二叉樹做簡單的寬度優先遍歷即可。不過本題有額外的要求,即同一層的節點必須列印在同一行上,並且要求輸出行號

本題使用了2個node型別的變數lastnlast。分別表示當前行的最右節點下一行的最右節點

如果發現遍歷到的節點正好等於last,則說明應該換行。換行後,令last=nlast

對於nlast更新,只要讓它一直跟蹤最新加入佇列的節點即可。易知,最新加入的節點一定是下一行的最右節點

public void printbylevel(node head) 

queuequeue = new linkedlist();

int level = 1;

node last = head;

node nlast = null;

queue.offer(head);

system.out.print("level " + (level++) + " : ");

while (!queue.isempty())

if (head.right != null)

if (head == last && !queue.isempty())

}system.out.println();

}

對於zigzag列印,最終的結果也只是偶數行倒序輸出而已,不過實現起來需要乙個雙端佇列

這裡需要額外說明一下,不能使用2個arraylist或是2個stack來實現。因為它們底層都是動態陣列,當元素數量達到一定規模時將發生擴容,擴容的時間複雜度為o(n),是比較高的,並且用這個結構增加和刪除元素時間複雜度也比較高。用該資料結構來實現,不夠「純粹」和「乾淨」。stack最好平時也儘量減少使用,詳見:為什麼jdk建議使用arraydeque實現棧

。使用雙端佇列實現zigzag列印時,需要注意:

如果是從左到右的過程,那麼一律從dq的頭部彈出節點。如果當前節點有孩子節點,則讓孩子節點以先左後右的順序從尾部加入dq;

如果是從右到左的過程,那麼一律從dq的尾部彈出節點。如果當前節點有孩子節點,則讓孩子節點以先右後左的順序從頭部加入dq。

當遍歷到的節點剛好等於last,則進行上面2種列印的切換

不過如何確定下一層的最後節點呢?不難發現,下一層最後列印的節點就是當前層有孩子節點的節點中最先加入dq的孩子節點

public void printbyzigzag(node head) 

dequedq = new linkedlist();

int level = 1;

boolean lr = true;

node last = head;

node nlast = null;

dq.offerfirst(head);

pringlevelandorientation(level++, lr);

while (!dq.isempty())

if (head.right != null)

} else

if (head.left != null)

}system.out.print(head.value + " ");

if (head == last && !dq.isempty())

}system.out.println();

}public void pringlevelandorientation(int level, boolean lr)

按層列印二叉樹

二叉樹是一種常見的資料結構,由n 你 0 個節點構成,每個節點最多有兩個子二叉樹。由二叉樹的定義可知,一棵二叉樹由三部分組成 根節點 左子樹和右子樹。二叉樹的遍歷方式有先序遍歷 中序遍歷和後序遍歷。先序遍歷 首先訪問根節點,然後訪問根節點左孩子,再訪問根節點的右孩子。中序遍歷 首先訪問根節點左孩子,...

按層列印二叉樹

從上到下按層列印二叉樹,同一層結點從左至右輸出,每一層輸出一行 思路 1 廣度遍歷,利用佇列思想 2 要有2個佇列,分別存放當前層的節點 和 下一層的節點 class node 節點類 def init self,val self.val val self.left none self.right ...

二叉樹3 二叉樹按層遍歷列印

題目 有一棵二叉樹,請設計乙個演算法,按照層次列印這棵二叉樹。給定二叉樹的根結點root,請返回列印結果,結果按照每一層乙個陣列進行儲存,所有陣列的順序按照層數從上往下,且每一層的陣列內元素按照從左往右排列。保證結點數小於等於500。思路 對於二叉樹,除了先序遍歷 中序遍歷 後序遍歷之外,常用的遍歷...