1. 程式人生 > >二叉樹相關演算法——建立、遍歷、求深度和廣度

二叉樹相關演算法——建立、遍歷、求深度和廣度

二叉樹相關的演算法,遍歷使用了遞迴和迭代兩種演算法,可作為結果對比。
理解起來不難,直接上程式碼,有空再補下注釋說明原理。

package com.junyang.algodemo.Tree;

import java.util.LinkedList;
import java.util.Stack;

public class TreeUtil {
    private static final int DEEP = 5;

    /* 建立一個深度為deep的滿二叉樹,目的是為驗證其它演算法 */
    public static TreeNode createTree(int deep) {
        /* 處理deep為0 和為1的特殊情況 */
if (0 >= deep) { return null; } int count = 0; TreeNode root = new TreeNode(count++); if (1 == deep) { return root; } /* 滿二叉樹建立完成的條件為,當前這一層達到2的 deep-1 次方 */ double maxLayerNum = Math.pow(2f, deep - 1f); TreeNode last = root; /* 通過佇列按層建立二叉樹 */
LinkedList<TreeNode> queue = new LinkedList<>(); queue.add(root); int width = 0; while (!queue.isEmpty()) { TreeNode temp = queue.remove(); temp.left = new TreeNode(count++); temp.right = new TreeNode(count++); queue.add(temp.left); queue.add(temp.right); width += 2
; if (width == maxLayerNum) { return root; } if (temp == last) { last = last.right; width = 0; } } return root; } /* 按層遍歷同時按行顯示 */ public static void printTreeForLayer(TreeNode root) { if (null == root) { return; } LinkedList<TreeNode> queue = new LinkedList<>(); queue.add(root); TreeNode last = root; TreeNode nlast = root; int lineNum = 1; System.out.print("num[" + lineNum++ + "]:"); while (!queue.isEmpty()) { TreeNode temp = queue.remove(); if (null != temp.left) { queue.add(temp.left); nlast = temp.left; } if (null != temp.right) { queue.add(temp.right); nlast = temp.right; } System.out.print(temp.data + " "); if (temp == last) { System.out.println(); if (!queue.isEmpty()) { System.out.print("num[" + lineNum++ + "]:"); } last = nlast; } } } /* 先序遍歷 —— 遞迴 */ public static void printTreeForRootFirst1(TreeNode root) { if (root == null) { return; } System.out.print(root.data + " "); printTreeForRootFirst1(root.left); printTreeForRootFirst1(root.right); } /* 先序遍歷 —— 迭代*/ public static void printTreeForRootFirst2(TreeNode root) { if (null == root) { return; } Stack<TreeNode> stack = new Stack<>(); stack.push(root); while (!stack.isEmpty()) { TreeNode top = stack.pop(); System.out.print(top.data + " "); if (top.right != null) { stack.push(top.right); } if (top.left != null) { stack.push(top.left); } } } /* 中序遍歷 —— 遞迴 */ public static void printTreeForRootMiddle(TreeNode root) { if (root == null) { return; } printTreeForRootMiddle(root.left); System.out.print(root.data + " "); printTreeForRootMiddle(root.right); } /* 中序遍歷 —— 迭代 */ public static void printTreeForRootMiddle2(TreeNode root) { if (root == null) { return; } Stack<TreeNode> stack = new Stack<>(); TreeNode cur = root; while (!stack.isEmpty() || cur != null) { if (cur != null) { stack.push(cur); cur = cur.left; } else { cur = stack.pop(); System.out.print(cur.data + " "); cur = cur.right; } } } /* 後序遍歷 —— 遞迴 */ public static void printTreeForRootLast(TreeNode root) { if (root == null) { return; } printTreeForRootLast(root.left); printTreeForRootLast(root.right); System.out.print(root.data + " "); } /* 後序遍歷 —— 迭代 */ public static void printTreeForRootLast2(TreeNode root) { if (root == null) { return; } Stack<TreeNode> stack = new Stack<>(); Stack<TreeNode> output = new Stack<>(); stack.push(root); while (!stack.isEmpty()) { TreeNode temp = stack.pop(); output.push(temp); if (null != temp.left) { stack.push(temp.left); } if (null != temp.right) { stack.push(temp.right); } } while (!output.isEmpty()) { System.out.print(output.pop().data + " "); } } /* 獲取二叉樹的寬度 */ public static int getWidth(TreeNode root) { if (null == root) { return 0; } int maxWidth = 1; int curWidth = 0; LinkedList<TreeNode> linkedList = new LinkedList<>(); linkedList.add(root); TreeNode last = root; TreeNode nlast = root; while (!linkedList.isEmpty()) { TreeNode temp = linkedList.remove(); if (null != temp.left) { linkedList.add(temp.left); nlast = temp.left; curWidth++; } if (null != temp.right) { linkedList.add(temp.right); nlast = temp.right; curWidth++; } if (temp == last) { last = nlast; maxWidth = maxWidth > curWidth ? maxWidth : curWidth; curWidth = 0; } } return maxWidth; } /* 獲取二叉樹的深度 */ public static int getDeep(TreeNode root) { if (null == root) { return 0; } int leftDeep = 0; if (root.left != null) { leftDeep = getDeep(root.left); } int rightDeep = 0; if (root.right != null) { rightDeep = getDeep(root.right); } return (rightDeep > leftDeep ? rightDeep : leftDeep) + 1; } public static void main(String[] args) { TreeNode root = createTree(DEEP); System.out.println("按層遍歷"); printTreeForLayer(root); System.out.println("先序遍歷"); printTreeForRootFirst1(root); System.out.println(); printTreeForRootFirst2(root); System.out.println(); System.out.println("中序遍歷"); printTreeForRootMiddle(root); System.out.println(); printTreeForRootMiddle2(root); System.out.println(); System.out.println("後序遍歷"); printTreeForRootLast(root); System.out.println(); printTreeForRootLast2(root); System.out.println(); System.out.println("deep:" + getDeep(root)); System.out.println("width:" + getWidth(root)); } }

輸出:

按層遍歷
num[1]:0 
num[2]:1 2 
num[3]:3 4 5 6 
num[4]:7 8 9 10 11 12 13 14 
num[5]:15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 
先序遍歷
0 1 3 7 15 16 8 17 18 4 9 19 20 10 21 22 2 5 11 23 24 12 25 26 6 13 27 28 14 29 30 
0 1 3 7 15 16 8 17 18 4 9 19 20 10 21 22 2 5 11 23 24 12 25 26 6 13 27 28 14 29 30 
中序遍歷
15 7 16 3 17 8 18 1 19 9 20 4 21 10 22 0 23 11 24 5 25 12 26 2 27 13 28 6 29 14 30 
15 7 16 3 17 8 18 1 19 9 20 4 21 10 22 0 23 11 24 5 25 12 26 2 27 13 28 6 29 14 30 
後序遍歷
15 16 7 17 18 8 3 19 20 9 21 22 10 4 1 23 24 11 25 26 12 5 27 28 13 29 30 14 6 2 0 
15 16 7 17 18 8 3 19 20 9 21 22 10 4 1 23 24 11 25 26 12 5 27 28 13 29 30 14 6 2 0 
deep:5
width:16