1. 程式人生 > >二叉樹的三種遍歷方式java實現

二叉樹的三種遍歷方式java實現

二叉樹的特點:

  1. 性質1:在二叉樹的第i層上至多有2^(i-1)個節點(i >= 1)
  2. 性質2:深度為k的二叉樹至多有2^k-1個節點(k >=1)
  3. 性質3:對於任意一棵二叉樹T而言,其葉子節點數目為N0,度為2的節點數目為N2,則有N0 = N2 + 1。
  4. 性質4:具有n個節點的完全二叉樹的深度 。

二叉樹遍歷java實現

package com.person.spring.simple.java.sort;

import java.util.ArrayList;
import java.util.List;

public class Tree {
  private Node root;
  private List<Node> list = new ArrayList<Node>();

  public Tree() {
    init();
  }

  // 樹的初始化:先從葉節點開始,由葉到根
  public void init() {
    Node x = new Node("X", null, null);
    Node y = new Node("Y", null, null);
    Node d = new Node("d", x, y);
    Node e = new Node("e", null, null);
    Node f = new Node("f", null, null);
    Node c = new Node("c", e, f);
    Node b = new Node("b", d, null);
    Node a = new Node("a", b, c);
    root = a;
  }

  // 定義節點類:
  private class Node {
    private String data;
    private Node lchid;// 定義指向左子樹的指標
    private Node rchild;// 定義指向右子樹的指標

    public Node(String data, Node lchild, Node rchild) {
      this.data = data;
      this.lchid = lchild;
      this.rchild = rchild;
    }
  }

  /**
   * 對該二叉樹進行前序遍歷 結果儲存到list中 abdxy  cef
   * 前序遍歷:根左右
   */
  public void preOrder(Node node) {

    list.add(node); // 先將根節點存入list
    // 如果左子樹不為空繼續往左找,在遞迴呼叫方法的時候一直會將子樹的根存入list,這就做到了先遍歷根節點
    if (node.lchid != null) {
      preOrder(node.lchid);
    }
    // 無論走到哪一層,只要當前節點左子樹為空,那麼就可以在右子樹上遍歷,保證了根左右的遍歷順序
    if (node.rchild != null) {
      preOrder(node.rchild);
    }
  }

  /**
   * 對該二叉樹進行序遍歷 結果儲存到list中  xdyba  ecf
   * 中序遍歷:左根右
   */
  public void inOrder(Node node) {
    if (node.lchid != null) {
      inOrder(node.lchid);
    }
    list.add(node);
    if (node.rchild != null) {
      inOrder(node.rchild);
    }
  }

  /**
   * 對該二叉樹進行後序遍歷 結果儲存到list中  xydb efc a
   * 後序遍歷:左右根
   */
  public void postOrder(Node node) {
    if (node.lchid != null) {
      postOrder(node.lchid);
    }
    if (node.rchild != null) {
      postOrder(node.rchild);
    }
    list.add(node);

  }

  /**
   * 返回當前數的深度 說明: 1、如果一棵樹只有一個結點,它的深度為1。 2、如果根結點只有左子樹而沒有右子樹,那麼樹的深度是其左子樹的深度加1;
   * 3、如果根結點只有右子樹而沒有左子樹,那麼樹的深度應該是其右子樹的深度加1; 4、如果既有右子樹又有左子樹,那該樹的深度就是其左、右子樹深度的較大值再加1。
   * 
   * @return
   */
  public int getTreeDepth(Node node) {

    if (node.lchid == null && node.rchild == null) {
      return 1;
    }
    int left = 0, right = 0;
    if (node.lchid != null) {
      left = getTreeDepth(node.lchid);
    }
    if (node.rchild != null) {
      right = getTreeDepth(node.rchild);
    }
    return left > right ? left + 1 : right + 1;
  }


  // 得到遍歷結果
  public List<Node> getResult() {
    return list;
  }

  public static void main(String[] args) {
    Tree tree = new Tree();
    System.out.println("根節點是:" + tree.root);
    // tree.preOrder(tree.root);
    tree.postOrder(tree.root);
    for (Node node : tree.getResult()) {
      System.out.println(node.data);
    }
    System.out.println("樹的深度是" + tree.getTreeDepth(tree.root));

  }

}