- import java.util.ArrayList;
- import java.util.LinkedList;
- import java.util.List;
- public class LevelTraverseBinaryTree {
- /**
- * 編程之美 分層遍歷二叉樹
- * 之前已經用隊列實現過二叉樹的層次遍歷,但這次要求輸出換行,因此要標記什麼時候要換行:
- * 用inCount記錄某層有多少個元素,outCount記錄當前輸出了多少個元素;當inCount==outCount時,就說明某層元素已經完全輸出,此時應該換行(outCount清零)
- * 此外,觀察發現,當第K層元素全部出隊(並已將各自左右孩子入隊)後,隊列裏面剛好存放了第K+1層的所有元素,不多不少,所以有:inCount = queue.size();
- *
- * 書上的擴展問題也很有意思(從下往上分層輸出),既然是反過來輸出,第一反應是利用棧
- * 但同時又要記錄何時換行(每行有多少個元素),只好用ArrayList模擬一個“僞棧”:
- * 1、第一步操作和“從上往下分層輸出”是類似的:從root開始遍歷,並將所有元素放入“隊列”(ArrayList),用-1表示一層的結束
- * 2、輸出。不是從隊頭開始,而是從隊尾開始,依次輸出
- * 分析到這裏,這裏面的ArrayList定義爲“雙向隊列”更合適
- */
- public static void main(String[] args) {
- /*
- __1__
- / \
- __2__ 3__
- / \ \
- 4 __5__ 6
- 7 8
- */
- int[] src = { 1, 2, 3, 4, 5, 0, 6, 0, 0, 7, 8 };
- LevelTraverseBinaryTree data = new LevelTraverseBinaryTree();
- Node root = data.createTree(src);
- data.traverseByLevelFromTop(root);
- System.out.println();
- data.traverseByLevelFromBottom(root);
- }
- /*
- 從上往下分層輸出
- 1
- 2 3
- 4 5 6
- 7 8
- */
- public void traverseByLevelFromTop(Node node) {
- if (node == null) {
- return;
- }
- LinkedList<Node> queue = new LinkedList<Node>();
- queue.addLast(node);
- int inCount = 1;
- int outCount = 0;
- while (!queue.isEmpty()) {
- Node curNode = queue.pollFirst();
- System.out.print(curNode.getData() + " ");
- outCount++;
- if (curNode.getLeft() != null) {
- queue.addLast(curNode.getLeft());
- }
- if (curNode.getRight() != null) {
- queue.addLast(curNode.getRight());
- }
- if (outCount == inCount) {
- System.out.println();
- inCount = queue.size();
- outCount = 0;
- }
- }
- }
- /*
- 從下往上分層輸出
- 7 8
- 4 5 6
- 2 3
- 1
- */
- public void traverseByLevelFromBottom(Node node) {
- if (node == null) {
- return;
- }
- List<Node> list = new ArrayList<Node>();
- list.add(node);
- list.add(new Node(-1)); //-1表示一層結束,打印時要換行
- int i = 0;
- int size = list.size();
- while (i < size) {
- Node curNode = list.get(i);
- /*交換下面這兩個操作,可實現輸出:
- 8 7
- 6 5 4
- 3 2
- 1
- */
- if (curNode.getRight() != null) {
- list.add(curNode.getRight());
- }
- if (curNode.getLeft() != null) {
- list.add(curNode.getLeft());
- }
- i++;
- if (i == size) {
- if (curNode.getData() != -1 && curNode.getLeft() == null && curNode.getRight() == null) { //已經遍歷到最底層的最後一個元素,結束循環
- break;
- }
- size = list.size();
- list.add(new Node(-1));
- }
- }
- //從後往前遍歷,相當於“棧”
- for (size = list.size(), i = size - 1; i >=0; i--) {
- int val = list.get(i).getData();
- if (val == -1) {
- System.out.println();
- } else {
- System.out.print(val + " ");
- }
- }
- }
- public Node createTree(int[] data){
- List<Node> nodeList=new ArrayList<Node>();
- for(int each:data){
- Node n=new Node(each);
- nodeList.add(n);
- }
- int lastRootIndex=data.length/2-1;
- for(int i=0;i<=lastRootIndex;i++){
- Node root=nodeList.get(i);
- Node left=nodeList.get(i*2+1);
- if(left.getData()!=0){
- root.setLeft(left);
- }else{
- root.setLeft(null);
- }
- if(i*2+2<data.length){
- Node right=nodeList.get(i*2+2);
- if(right.getData()!=0){
- root.setRight(right);
- }else{
- root.setRight(null);
- }
- }
- }
- Node root=nodeList.get(0);
- return root;
- }
- }
- class Node {
- int data;
- Node left;
- Node right;
- Node(int data) {
- this.data = data;
- }
- public int getData() {
- return data;
- }
- public void setData(int data) {
- this.data = data;
- }
- public Node getLeft() {
- return left;
- }
- public void setLeft(Node left) {
- this.left = left;
- }
- public Node getRight() {
- return right;
- }
- public void setRight(Node right) {
- this.right = right;
- }
- }
二叉樹的遍歷Java實現_world
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.