二叉樹的層序遍歷
給你一個二叉樹,請你返回其按 層序遍歷 得到的節點值。 (即逐層地,從左到右訪問所有節點)。
來源:https://leetcode-cn.com/problems/binary-tree-level-order-traversal/
基本思路:這裡通過佇列實現迭代來實現的
1、定義一個佇列,用於存放節點
2、判斷佇列是否為空,如果不為空,那麼首先獲取當前佇列中的節點個數,然後再就從佇列中跳出一個節點,然後通過判斷這個節點左右子節點是否為null,從而可以知道是否要將它的左右子節點壓入佇列中,但是值得注意的是,必須要獲取當前佇列中的節點個數,從而可以知道每從佇列中跳出一個節點時,往集合中新增的節點之前有多少個節點
3、重複步驟2,直到佇列為空
節點類:
public class Node {
public int value;
public Node left;
public Node right;
public Node(int value){
this.value = value;
}
@Override
public String toString() {
return value+" ";
}
}
測試類:
/**
* 二叉樹的層序遍歷(即從左到右進行輸出,並且逐層訪問
* 基本思路:通過佇列實現迭代,從而實現二叉樹的層序遍歷
* 1、將根節點壓入到佇列中
* 2、之後,將從佇列中跳出一個節點,並且判斷這個新跳出節點的左右子節點是否為空,如果為空,就不要
* 將其壓入到佇列中去,否則就將其壓入佇列中
* 3、重複2操作,知道佇列為空
*/
public class TreeCenXuDisplay {
public static List<List<Integer>> list = new ArrayList<>();
public int[] arr = {4,5,8,10,12,15,18};//通過中序遍歷得到的陣列來構建二叉樹
public static void main(String[] args) {
TreeCenXuDisplay test = new TreeCenXuDisplay();
Node root = test.buildTree(0,test.arr.length);
System.out.print("通過中序遍歷得到的二叉樹的前序遍歷: ");
test.display(root);
System.out.println();
System.out.println("二叉樹的層序遍歷: ");
test.display2(root);
for (List<Integer> list2: list) {
System.out.println(list2);
}
}
/**
* 將一個按照升序排列的有序陣列(即二叉樹中序遍歷得到的),轉換為一棵高度平衡二叉搜尋樹。
*本題中,一個高度平衡二叉樹是指一個二叉樹每個節點 的左右兩個子樹的高度差的絕對值不超過 1。
* @param start
* @param end
*/
public Node buildTree(int start, int end) {
if(start >= end){
/**
* 如果範圍不正確的時候,結束遞迴,注意這裡必須要有=,因為end一開始傳遞的引數時陣列的長度,此時
* end - start表示的是陣列的長度,此時如果start = end是,表示的是有0個元素,所以結束遞迴,
* start > end就更不用說了
*/
return null;
}
int mid = (start + end) / 2;//陣列中間或者中間偏一個節點是根節點
Node root = new Node(arr[mid]);//新建一個根節點
//構建左子樹、右子樹
root.left = buildTree(start,mid);
root.right = buildTree(mid + 1,end);
return root;
}
/**
* 樹的前序遍歷
*/
public void display(Node root) {
if(root == null){
return;
}
System.out.print(root + " ");
display(root.left);
display(root.right);
}
/**
* 樹的層序遍歷:通過一個佇列實現迭代,從而實現層序遍歷
* 基本思路:
* 1、定義一個佇列,用於存放節點
* 2、判斷佇列是否為空,如果不為空,那麼首先獲取當前佇列中的節點個數,然後再就從佇列中跳出一個節點,然後通過判斷這個
* 節點左右子節點是否為null,從而可以知道是否要將它的左右子節點壓入佇列中,但是值得注意的是,必須要獲取當前佇列中的節點個數,從而可以知道每從佇列中跳出一個節點時,往集合中新增的節點有多少個
* 3、重複步驟2,知道佇列為空
*/
public void display2(Node root){
//定義一個佇列
Queue<Node> queue = new LinkedList<>();
//定義一個集合
ArrayList<Integer> arrayList = null;
//將根節點新增到佇列中
queue.offer(root);
//通過判斷佇列是否為空,從而將其左右子節點新增到佇列中
while(!queue.isEmpty()){
arrayList = new ArrayList<>();
//獲取當前佇列中的節點個數
int size = queue.size();
for (int i = 0; i < size; i++) {
//注意的是,這裡的迴圈條件不可以時queue.size,否則就會發生報錯
//將佇列中跳出一個根節點,並將其對應的值新增到集合arrayList中
root = queue.poll();
arrayList.add(root.value);
//判斷當前根節點的左右子節點是否為空,如果不為空,就新增到佇列中
if(root.left != null){
queue.offer(root.left);
}
if(root.right != null){
queue.offer(root.right);
}
}
list.add(arrayList);//將一個集合新增到list中
}
}
}
運算結果:
值得注意的是,構造層序遍歷的程式碼不可以是這樣子的,即不可以是單層迴圈:
/**
* 這裡沒有直到每一層中的節點個數,並且只是單層迴圈,那麼每一次只能向佇列中新增兩個節點
* 所以需要有巢狀迴圈,並且第二層迴圈的迴圈條件是要直到每一層中節點個數,即佇列的節點個數
* @param root
*/
private void display3(Node root) {
//新建一個佇列
Queue<Node> queue = new LinkedList<>();
//新建一個集合
ArrayList<Integer> arrayList = new ArrayList<>();
//將根節點壓入到對了中
queue.offer(root);
arrayList.add(root.value);
list.add(arrayList);
while(!queue.isEmpty()){
arrayList = new ArrayList<>();
root = queue.poll();//從佇列中跳出根節點
//判斷它的左右子節點是否為空,如果不為空,就新增到佇列中
if(root.left != null){
queue.offer(root.left);
arrayList.add(root.left.value);
}
if(root.right != null){
queue.offer(root.right);
arrayList.add(root.right.value);
}
list.add(arrayList);
}
}
否則對應的錯誤結果是這樣的:
也正如此,所以需要通過迴圈巢狀實現二叉樹的層序遍歷,並且需要直到每一層的節點個數。
相關文章
- 層序遍歷二叉樹二叉樹
- 二叉樹的建立、前序遍歷、中序遍歷、後序遍歷二叉樹
- 二叉樹的四種遍歷方法:先序,中序,後序,層序二叉樹
- 二叉樹建立,前序遍歷,中序遍歷,後序遍歷 思路二叉樹
- 建立二叉樹:層次遍歷--樹的寬度高度,後序遍歷--祖先節點二叉樹
- 二叉樹--後序遍歷二叉樹
- 144.二叉樹的前序遍歷145.二叉樹的後序遍歷 94.二叉樹的中序遍歷二叉樹
- 二叉樹的按層遍歷二叉樹
- 二叉樹:構造二叉樹(通過前序和中序遍歷)、映象翻轉、層次遍歷二叉樹
- python-二叉樹:前、中、後、層序遍歷Python二叉樹
- 根據二叉樹的前序遍歷和中序遍歷輸出二叉樹;二叉樹
- 【C++】返回每一層二叉樹的平均值(層序遍歷)C++二叉樹
- LeetCode102.二叉樹的層序遍歷LeetCode二叉樹
- 二叉樹的先,中,後序遍歷二叉樹
- 二叉樹的先中後序遍歷二叉樹
- 二叉樹的前中後序遍歷二叉樹
- 3143 二叉樹的序遍歷二叉樹
- 非遞迴遍歷二叉樹的四種策略-先序、中序、後序和層序遞迴二叉樹
- 遞迴和迭代實現二叉樹先序、中序、後序和層序遍歷遞迴二叉樹
- LeetCode-107-二叉樹的層序遍歷 IILeetCode二叉樹
- 資料結構與演算法——二叉樹的前序遍歷,中序遍歷,後序遍歷資料結構演算法二叉樹
- LintCode 前序遍歷和中序遍歷樹構造二叉樹二叉樹
- 二叉樹的前序、中序、後序三種遍歷二叉樹
- 94. 二叉樹的中序遍歷(迭代)二叉樹
- 二叉樹中序和後序遍歷表示式二叉樹
- 非遞迴先序遍歷二叉樹遞迴二叉樹
- 388,先序遍歷構造二叉樹二叉樹
- 根據前序遍歷序列、中序遍歷序列,重建二叉樹二叉樹
- Leetcode 演算法題解系列 - 二叉樹的層序遍歷LeetCode演算法二叉樹
- 二叉樹的層序遍歷詳細講解(附完整C++程式)二叉樹C++
- 二叉樹的前序,中序,後序遍歷方法總結二叉樹
- 中序線索二叉樹的建立與遍歷二叉樹
- 二叉樹(BST)中序遍歷的三種方法二叉樹
- LeeCode-94. 二叉樹的中序遍歷二叉樹
- 【模板題】- 94. 二叉樹的中序遍歷二叉樹
- 二叉樹的遍歷二叉樹
- 通過層次遍歷計算二叉樹的層數二叉樹
- 層序遍歷樹的節點,佇列實現佇列