1. 程式人生 > >二叉樹三種遍歷 (Java)

二叉樹三種遍歷 (Java)

以前學資料結構的時候是用C學的,現在重新複習一下資料結構裡用的比較多的二叉樹,用Java實現。好啦,廢話不多說啦!!

我們知道二叉樹有三種遍歷方式:前序(根左右)、中序(左根右)、後序(左右根)。每種遍歷方式其實就是一個遞迴呼叫。

步驟:

1、將陣列中的元素賦值給二叉樹(通常這個過程叫做建樹)。

2、然後對於每種遍歷方式進行遞迴呼叫。

具體程式碼如下:

import java.util.LinkedList;
import java.util.List;

/**
 * 功能:把一個數組的值存入二叉樹中,然後進行3種方式的遍歷
 * 
 * 參考資料: 資料結構(C語言版)嚴蔚敏
 * 
 * @author bxk88 @date: 2015-08-21
 * 
 */
public class BinTreeTraverse{

	private int[] array = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	private static List<Node> nodeList = null;

	/**
	 * 內部類:節點
	 * 
	 * @author bxk88 @date: 2015-08-21
	 * 
	 */
	private static class Node {
		Node leftChild;
		Node rightChild;
		int data;

		Node(int newData) {
			leftChild = null;
			rightChild = null;
			data = newData;
		}
	}

	public void createBinTree() {
		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 static void preOrderTraverse(Node node) {
		if (node == null)
			return;
		System.out.print(node.data + " ");
		preOrderTraverse(node.leftChild);
		preOrderTraverse(node.rightChild);
	}

	/**
	 * 中序遍歷
	 * 
	 * 這三種不同的遍歷結構都是一樣的,只是先後順序不一樣而已
	 * 
	 * @param node
	 *            遍歷的節點
	 */
	public static void inOrderTraverse(Node node) {
		if (node == null)
			return;
		inOrderTraverse(node.leftChild);
		System.out.print(node.data + " ");
		inOrderTraverse(node.rightChild);
	}

	/**
	 * 後序遍歷
	 * 
	 * 這三種不同的遍歷結構都是一樣的,只是先後順序不一樣而已
	 * 
	 * @param node
	 *            遍歷的節點
	 */
	public static void postOrderTraverse(Node node) {
		if (node == null)
			return;
		postOrderTraverse(node.leftChild);
		postOrderTraverse(node.rightChild);
		System.out.print(node.data + " ");
	}

	public static void main(String[] args) {

		BinTreeTraverse binTree = new BinTreeTraverse();
		binTree.createBinTree();
		// nodeList中第0個索引處的值即為根節點
		Node root = nodeList.get(0);

		System.out.println("先序遍歷:");
		preOrderTraverse(root);
		System.out.println();

		System.out.println("中序遍歷:");
		inOrderTraverse(root);
		System.out.println();

		System.out.println("後序遍歷:");
		postOrderTraverse(root);
	}

}

/*
輸出結果:
先序遍歷:
1 2 4 8 9 5 3 6 7
中序遍歷:
8 4 9 2 5 1 6 3 7
後序遍歷:
8 9 4 5 2 6 7 3 1
*/

再上一個例子

/**
 * 二叉樹遍歷
 *
 *@author baoxukai
 *@version 1.0
 *
 */

class BinaryTree {
 
	 int data;      //根節點資料
	 BinaryTree left;    //左子樹
	 BinaryTree right;   //右子樹
	 
	 public BinaryTree(int data)    //例項化二叉樹類
	 {
		  this.data = data;
		  left = null;
		  right = null;
	 }
	 
	 public void insert(BinaryTree root,int data){     //向二叉樹中插入子節點

		  if(data>root.data)                               //二叉樹的左節點都比根節點小
		  {
			   if(root.right==null){
					root.right = new BinaryTree(data);
			   }else{
					this.insert(root.right, data);  //遞迴呼叫
			   }

		  }else{                                          //二叉樹的右節點都比根節點大
			   
			   if(root.left==null){
					root.left = new BinaryTree(data);
			   }else{
					this.insert(root.left, data);
			   }
		  }
	 }

}

//當建立好二叉樹類後可以建立二叉樹例項,並實現二叉樹的先根遍歷,中根遍歷,後根遍歷,程式碼如下:


public class BinTreeTraverseTest {
 
	 public static void preOrder(BinaryTree root){  //先根遍歷
		  if(root!=null){
		   System.out.print(root.data+"-");
		   preOrder(root.left);
		   preOrder(root.right);
		  }
	 }
	 
	 public static void inOrder(BinaryTree root){     //中根遍歷

		  if(root!=null){
		   inOrder(root.left);
		   System.out.print(root.data+"--");
		   inOrder(root.right);
		  }
	 }
	 
	 public static void postOrder(BinaryTree root){    //後根遍歷

		  if(root!=null){
		   postOrder(root.left);
		   postOrder(root.right);
		   System.out.print(root.data+"---");
		  }
	 }
	 

	 public static void main(String[] args){

		  int[] array = {12,76,35,22,16,48,90,46,9,40};

		  BinaryTree root = new BinaryTree(array[0]);   //建立二叉樹
		  for(int i=1;i<array.length;i++){
			 root.insert(root, array[i]);       //向二叉樹中插入資料
		  }

		  System.out.println("先根遍歷:");
		  preOrder(root);
		  System.out.println();

		  System.out.println("中根遍歷:");
		  inOrder(root);
		  System.out.println();

		  System.out.println("後根遍歷:");
		  postOrder(root);
	 }


 }

 /*
 程式輸出:
先根遍歷:
12-9-76-35-22-16-48-46-40-90-
中根遍歷:
9--12--16--22--35--40--46--48--76--90--
後根遍歷:
9---16---22---40---46---48---35---90---76---12---
*/