題目:二叉樹的按層列印與zigzag列印
《程式設計師**面試指南》第39題 p132 難度:尉
★★☆☆
按層列印原本是非常基礎的內容,對二叉樹做簡單的寬度優先遍歷即可。不過本題有額外的要求,即同一層的節點必須列印在同一行上,並且要求輸出行號。
本題使用了2個node型別的變數,last和nlast。分別表示當前行的最右節點與下一行的最右節點。
如果發現遍歷到的節點正好等於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。思路 對於二叉樹,除了先序遍歷 中序遍歷 後序遍歷之外,常用的遍歷...