按層次生成、遍歷二叉樹
對於二叉樹一般是按深度生成和遍歷,比如使用遞迴方法進行先序遍歷、中序遍歷、後序遍歷。這次我們按層次生成和遍歷二叉樹。
這種遍歷方式關鍵在於需要使用一個佇列儲存“已處理該節點,但還沒處理它的子節點”這樣的節點。
# Python程式碼
# Definition for singly-linked list.
class BinTree(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution(object) :
# 按層次建立二叉樹
def createBinTree(self, inputList):
# 尚未設定子節點的節點列表
nodeList = []
if (inputList == None) or (len(inputList) == 0):
return None
# 取出根元素
value = inputList.pop(0)
root = BinTree(value)
nodeList.append(root)
# 結束條件:所有值不為“#”的節點都設定了子節點,即nodeList為空
while len(nodeList) != 0:
leftValue = inputList.pop(0)
rightValue = inputList.pop(0)
if leftValue != '#' and rightValue != '#':
nodeLeft = BinTree(leftValue)
nodeRight = BinTree(rightValue)
# 每次取出兩個節點,加入到 “未設定子節點的節點列表”
nodeList.append(nodeLeft)
nodeList.append(nodeRight)
nodeList[0].left = nodeLeft
nodeList[0].right = nodeRight
# 為節點設定子節點後移出佇列
nodeList.pop(0)
# 若值為#,不需要處理,預設情況下節點的左右節點都為None
elif leftValue == '#' and rightValue != '#':
nodeRight = BinTree(rightValue)
nodeList.append(nodeRight)
nodeList[0].right = nodeRight
nodeList.pop(0)
elif rightValue == '#' and leftValue != '#':
nodeLeft = BinTree(leftValue)
nodeList.append(nodeLeft)
nodeList[0].left = nodeLeft
nodeList.pop(0)
else:
nodeList.pop(0)
return root
# 按層次遍歷二叉樹
def traverseBinTree(self, root):
nodeList = []
# 先將根節點加入佇列中
if root != None:
nodeList.append(root)
while len(nodeList) != 0:
# 輸出佇列第一個節點值,並將該節點的左右子節點加入佇列
node = nodeList.pop(0)
if node == None:
print('#')
continue
print(node.val)
leftNode = node.left
rightNode = node.right
nodeList.append(leftNode)
nodeList.append(rightNode)
s = Solution()
root = s.createBinTree(inputList = ['A', 'B', 'C', '#', 'D', '#', 'E', 'F', '#', '#', '#', '#', '#'])
s.traverseBinTree(root)
再進一步,不僅要按層次遍歷二叉樹,還要將每一層分別放在一個列表中。[ [3], [9,20], [15,7] ],實現這個要求重點在於確定何時一層遍歷完成。每層二叉樹的節點數目(含null節點)為上一層不含null節點的數目 * 2。可以採用兩個變數,記錄本層應該有多少個節點、和已經遍歷到多少個節點。二者相等時,本層節點遍歷結束。
// Java程式碼
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
public class Solution {
public List<List<Integer>> levelOrderBottom(TreeNode root) {
List<List<Integer>> resultList = new ArrayList<>();
// 記錄待遍歷的節點,每次取出隊首元素,並將其子節點(如果有)新增到佇列中。
// 當nodeList為空時,所有節點遍歷結束
List<TreeNode> nodeList = new ArrayList<>();
// 記錄二叉樹每一層的節點
List<Integer> layerList = new ArrayList<>();
// 本層應該有多少個節點
int eachLineNodeNum = 1;
// 已經遍歷到多少個節點
int currentNodeNum = 0;
// 本層有多少個空節點
int nullNodeNum = 0;
if (root != null)
nodeList.add(root);
while (nodeList.size() != 0) {
TreeNode node = nodeList.remove(0);
if (node == null) {
nullNodeNum ++;
currentNodeNum++;
if (eachLineNodeNum == currentNodeNum) {
// 下一層的節點數應為本層非空節點數 *2
eachLineNodeNum = (eachLineNodeNum - nullNodeNum) * 2;
currentNodeNum = 0;
nullNodeNum = 0;
// System.out.println("一層結束");
// 將layerList複製一份。
// 否則由於"引用傳遞"的特點,執行layerList.clear()時也會將resultList中的結果清除
if (layerList.size() != 0) {
resultList.add(new ArrayList<Integer>(layerList));
layerList.clear();
}
}
continue;
}
layerList.add(node.val);
currentNodeNum++;
if (eachLineNodeNum == currentNodeNum) {
eachLineNodeNum = (eachLineNodeNum - nullNodeNum) * 2;
currentNodeNum = 0;
nullNodeNum = 0;
// System.out.println("一層結束");
if (layerList.size() != 0) {
resultList.add(new ArrayList<Integer>(layerList));
layerList.clear();
}
}
TreeNode leftNode = node.left;
TreeNode rightNode = node.right;
nodeList.add(leftNode);
nodeList.add(rightNode);
}
Collections.reverse(resultList);
return resultList;
}
}
相關推薦
按層次生成、遍歷二叉樹
對於二叉樹一般是按深度生成和遍歷,比如使用遞迴方法進行先序遍歷、中序遍歷、後序遍歷。這次我們按層次生成和遍歷二叉樹。 這種遍歷方式關鍵在於需要使用一個佇列儲存“已處理該節點,但還沒處理它的子節點”這樣的節點。 # Python程式碼 # Definit
按層次順序建立和遍歷二叉樹
第一篇部落格,獻給了資料結構--二叉樹。 最近在學資料結構,總結一下二叉樹的按層次建立的方法,希望對此時的你有所幫助~ 有錯誤的地方,還望大神指出,或者有其他更好的方法,歡迎留言~ /*利用順序佇列,層次建立二叉樹*/ #include <iostream> using name
C++資料結構--按層次遍歷二叉樹
class node { public: T val; //節點值 node<T>* left; //左節點 node<T>* right; //右節點 node():val(T()),left(nullptr),right(nullptr){} node(T v,
按層次遍歷二叉樹演算法
問題:按層次遍歷二叉樹 在網上看了一些按層次遍歷二叉樹的演算法,這裡修改了一下通過佇列來按層次遍歷二叉樹的演算法 -------------------------------------------
JAVA按層級遍歷二叉樹
blog otn 二叉 all this java algorithm set com /** * @author cj 2017年7月14日下午1:14:31 */ package com.yuanye.algorithm; import java.util.Li
leet code Binary Tree Level Order Traversal II 層次遍歷二叉樹
leet code 題目:https://leetcode.com/problems/binary-tree-level-order-traversal-ii/ 層次遍歷二叉樹: 思路:使用佇列層次遍歷二叉樹, 考點: 1.使用佇列,先彈出佇列對頭,把隊頭元素的左節點和右節點加入佇列
水平遍歷二叉樹 程式碼中包含前序、中序、後序和水平遍歷四種
水平遍歷二叉樹要求一層一層從上往下從左往右遍歷,例如: 上面二叉樹的遍歷順序為:2、4、5、1、3 思路:利用佇列先進先出的性質 1、將根節點放入佇列 2、while迴圈佇列,只要佇列不為空,就取出第一個節點。獲取資料 3、將第二步取出的節點的左子節點和右子節點
java遍歷二叉樹:前序遍歷,中序遍歷,後序遍歷,遍歷深度,求葉子節點個數,層次遍歷
import java.util.ArrayDeque; import java.util.Queue; public class CreateTree { /** * @param args */ public static void main(Stri
層次遍歷二叉樹和採用棧的方式遍歷二叉樹
//中序遍歷非遞迴 @Override public void inOrderByStack() { System.out.println("中序遍歷非遞迴操作"); //建立棧 Deque<Node> stack=new LinkedList&
按層遍歷二叉樹並列印換行
package com.zyl.algorithm; import java.util.LinkedList; public class PrintBinaryTreeByFloor { publ
JAVA 先序、中序、後序、層序,遞迴非遞迴遍歷二叉樹
定義一個二叉樹 package com.niuke.binaryTree; public class binaryTree { int data; binaryTree left; binaryTree right; public binaryTree(int
【劍指offer】從上往下列印二叉樹,層次遍歷二叉樹【python】
題目描述 從上往下打印出二叉樹的每個節點,同層節點從左至右列印。 採用佇列的思想,出佇列則列印,然後左節點右節點分別入佇列 注意如果需要兩個不同的列表,一定不能用list = result = []這樣
二叉樹(6)----按層遍歷二叉樹
1、二叉樹定義 typedef struct BTreeNodeElement_t_ { void *data; } BTreeNodeElement_t; typedef struct BTreeNode_t_ { BTreeNodeElement_t
第六章 遍歷二叉樹及推導遍歷結果(前序、中序和後續)
二叉樹遍歷方法 下面幾種演算法是利用遞迴的方法實現的 - 前序遍歷:先列印輸出,再先序遍歷左子樹,最後先序遍歷右子樹 - 中序遍歷:中序遍歷左子樹,再列印,最後中序遍歷右子樹 - 後序遍歷:先後序遍歷左子樹,再後序遍歷右子樹,最後列印輸出 - 總結:前
資料結構 BFS層次遍歷二叉樹【C語言版本】
//案例輸入(其中的“#”表示空,並且輸入過程中不要加回車) 輸入序列ABC##DE#G##F### 輸入序列ABD##E##CF#G### 輸入序列ABD###C## #include <stdio.h> //測試OK,可以執行 #include <s
層次遍歷二叉樹以及遍歷第K層二叉樹
層次遍歷的時候用到了,STL中的佇列。 void LevelOrder(BtNode *ptr) { queue<BtNode*> que; que.push(ptr); while (!que.empty()) {
已知一個按先序序列輸入的字元序列,如abc,,de,g,,f,,,(其中逗號表示空節點)。請建立二叉樹並按中序和後序方式遍歷二叉樹,最後求出葉子節點個數和二叉樹深度。
這是一個標準的模板題 記下了就完事了! Input 輸入一個長度小於50個字元的字串。 Output 輸出共有4行: 第1行輸出中序遍歷序列; 第2行輸出後序遍歷序列; 第3行輸出葉子節點個數; 第4行輸出二叉樹深度。 Sample Input abc,,
[C/C++] 先序建立二叉樹| 先序、中序、後序遍歷二叉樹| 求二叉樹深度、節點數、葉節點數 演算法實現
/* * BinTree.h */ #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #defi
樹的學習——(遞迴構建二叉樹、遞迴非遞迴前序中序後序遍歷二叉樹、根據前序序列、中序序列構建二叉樹)
前言 最近兩個星期一直都在斷斷續續的學習二叉樹的資料結構,昨晚突然有點融匯貫通的感覺,這裡記錄一下吧 題目要求 給定前序序列,abc##de#g##f###,構建二叉樹,並且用遞迴和非遞迴兩種方法去做前序,中序和後序遍歷 二叉樹的資料結構 #define STACKSI
層次遍歷二叉樹-三種不同的方法
給定一棵二叉樹,要求進行分層遍歷,每層的節點值單獨列印一行,下圖給出事例結構: 對此二叉樹遍歷的結果應該是: 1, 2 , 3 4, 5, 6 7, 8 第一種方法,就是利用遞迴的方法,按層進行列印,我們把根節點當做第0層,之後層次依次增加,如果我們想列印第二層怎麼辦呢,