Java實現二叉樹及相關遍歷方式
在計算機科學中。二叉樹是每一個節點最多有兩個子樹的樹結構。通常子樹被稱作“左子樹”(left subtree)和“右子樹”(right subtree)。二叉樹常被用於實現二叉查找樹和二叉堆。
下面用Java實現對二叉樹的先序遍歷,中序遍歷,后序遍歷。廣度優先遍歷。深度優先遍歷。轉摘請注明:http://blog.csdn.net/qiuzhping/article/details/44830369
package com.qiuzhping.tree; import java.util.ArrayDeque; import java.util.LinkedList; import java.util.List; /** * 功能:把一個數組的值存入二叉樹中,然后進行3種方式的遍歷. * 構造的二叉樹: * 1 * / \ * 2 3 * / \ / \ * 4 5 6 7 * / \ * 8 9 * 先序遍歷:DLR * 1 2 4 8 9 5 3 6 7 * 中序遍歷:LDR * 8 4 2 9 5 1 6 3 7 * 后序遍歷:LRD * 8 9 4 5 2 6 7 3 1 * 深度優先遍歷 * 1 2 4 8 9 5 3 6 7 * 廣度優先遍歷 * 1 2 3 4 5 6 7 8 9 * @author Peter.Qiu * @version [Version NO, 2015年4月2日] * @see [Related classes/methods] * @since [product/module version] */ public class binaryTreeTest { private int[] array = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; private static List<Node> nodeList = null; /** * 內部類:節點 * */ private static class Node { Node leftChild; Node rightChild; int data; Node(int newData) { leftChild = null; rightChild = null; data = newData; } } /** 二叉樹的每個結點至多僅僅有二棵子樹(不存在度大於2的結點),二叉樹的子樹有左右之分,次序不能顛倒。<BR> * 二叉樹的第i層至多有2^{i-1}個結點。深度為k的二叉樹至多有2^k-1個結點;<BR> * 對不論什么一棵二叉樹T,假設其終端結點數為n_0,度為2的結點數為n_2。則n_0=n_2+1。<BR> *一棵深度為k,且有2^k-1個節點稱之為滿二叉樹;深度為k,有n個節點的二叉樹,<BR> *當且僅當其每個節點都與深度為k的滿二叉樹中,序號為1至n的節點相應時。稱之為全然二叉樹.<BR> * @author Peter.Qiu [Parameters description] * @return void [Return type description] * @exception throws [Exception] [Exception description] * @see [Related classes#Related methods#Related properties] */ public void createTree() { nodeList = new LinkedList<Node>(); // 將一個數組的值依次轉換為Node節點 for (int nodeIndex = 0; nodeIndex < array.length; nodeIndex++) { nodeList.add(new Node(array[nodeIndex])); } // 對前lastParentIndex-1個父節點依照父節點與孩子節點的數字關系建立二叉樹 for (int parentIndex = 0; parentIndex < array.length / 2 - 1; parentIndex++) { // 左孩子 nodeList.get(parentIndex).leftChild = nodeList .get(parentIndex * 2 + 1); // 右孩子 nodeList.get(parentIndex).rightChild = nodeList .get(parentIndex * 2 + 2); } // 最后一個父節點:由於最后一個父節點可能沒有右孩子,所以單獨拿出來處理 int lastParentIndex = array.length / 2 - 1; // 左孩子 nodeList.get(lastParentIndex).leftChild = nodeList .get(lastParentIndex * 2 + 1); // 右孩子,假設數組的長度為奇數才建立右孩子 if (array.length % 2 == 1) { nodeList.get(lastParentIndex).rightChild = nodeList .get(lastParentIndex * 2 + 2); } } /** * 先序遍歷 * * 這三種不同的遍歷結構都是一樣的,僅僅是先后順序不一樣而已 * * @param node * 遍歷的節點 */ public void preOrderTraverse(Node node) { if (node == null) return; System.out.print(node.data + " "); preOrderTraverse(node.leftChild); preOrderTraverse(node.rightChild); } /** * 中序遍歷 * * 這三種不同的遍歷結構都是一樣的,僅僅是先后順序不一樣而已 * * @param node * 遍歷的節點 */ public void inOrderTraverse(Node node) { if (node == null) return; inOrderTraverse(node.leftChild); System.out.print(node.data + " "); inOrderTraverse(node.rightChild); } /** * 后序遍歷 * * 這三種不同的遍歷結構都是一樣的。僅僅是先后順序不一樣而已 * * @param node * 遍歷的節點 */ public void postOrderTraverse(Node node) { if (node == null) return; postOrderTraverse(node.leftChild); postOrderTraverse(node.rightChild); System.out.print(node.data + " "); } /** * 深度優先遍歷,相當於先根遍歷 * 採用非遞歸實現 * 須要輔助數據結構:棧 */ public void depthOrderTraversal(Node root){ System.out.println("\n深度優先遍歷"); if(root==null){ System.out.println("empty tree"); return; } ArrayDeque<Node> stack=new ArrayDeque<Node>(); stack.push(root); while(stack.isEmpty()==false){ Node node=stack.pop(); System.out.print(node.data+ " "); if(node.rightChild!=null){ stack.push(node.rightChild); } if(node.leftChild!=null){ stack.push(node.leftChild); } } System.out.print("\n"); } /** * 廣度優先遍歷 * 採用非遞歸實現 * 須要輔助數據結構:隊列 */ public void levelOrderTraversal(Node root){ System.out.println("廣度優先遍歷"); if(root==null){ System.out.println("empty tree"); return; } ArrayDeque<Node> queue=new ArrayDeque<Node>(); queue.add(root); while(queue.isEmpty()==false){ Node node=queue.remove(); System.out.print(node.data+ " "); if(node.leftChild!=null){ queue.add(node.leftChild); } if(node.rightChild!=null){ queue.add(node.rightChild); } } System.out.print("\n"); } /** *構造的二叉樹: * 1 * / \ * 2 3 * / \ / \ * 4 5 6 7 * / \ * 8 9 * 先序遍歷:DLR * 1 2 4 8 9 5 3 6 7 * 中序遍歷:LDR * 8 4 2 9 5 1 6 3 7 * 后序遍歷:LRD * 8 9 4 5 2 6 7 3 1 * 深度優先遍歷 * 1 2 4 8 9 5 3 6 7 * 廣度優先遍歷 * 1 2 3 4 5 6 7 8 9 */ public static void main(String[] args) { binaryTreeTest binTree = new binaryTreeTest(); binTree.createTree(); // nodeList中第0個索引處的值即為根節點 Node root = nodeList.get(0); System.out.println("先序遍歷:"); binTree.preOrderTraverse(root); System.out.println(); System.out.println("中序遍歷:");//LDR binTree.inOrderTraverse(root); System.out.println(); System.out.println("后序遍歷:");//LRD binTree.postOrderTraverse(root); binTree.depthOrderTraversal(root);//深度遍歷 binTree.levelOrderTraversal(root);//廣度遍歷 } }