以下代碼實現二叉樹的構建,先序,中序,後序,層次,遞歸,非遞歸的遍歷
package AlgorithmDesign;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;
public class TreeTraverse{
int array[]=new int[]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; //數組用以存放構建二叉樹的數據
LinkedList<Node> nodelist=null; //鏈表用以存放二叉樹的結點
class Node { //內部類 定義節點
Node left;
Node right;
int data;
boolean flag;
public Node(int Data){ //內部類構造函數
left=null;
right=null;
data=Data;
flag=false;
}
}
//根據數組中的數創建二叉樹
public void creatTree(){
nodelist=new LinkedList<Node>();
// 將一個數組的值依次轉換爲Node節點
for(int i=0;i<array.length;i++){
nodelist.add(new Node(array[i]));
}
// 對前lastParentIndex-1個父節點按照父節點與孩子節點的數字關係建立二叉樹
for(int ParentIndex=0;ParentIndex<array.length/2-1;ParentIndex++){
// 左孩子
nodelist.get(ParentIndex).left=nodelist.get(2*ParentIndex+1);
//右孩子
nodelist.get(ParentIndex).right=nodelist.get(2*ParentIndex+2);
}
// 最後一個父節點:因爲最後一個父節點可能沒有右孩子,所以單獨拿出來處理
int lastParentIndex=array.length/2-1;
// 只建立左孩子
if(array.length%2==0){
nodelist.get(lastParentIndex).left=nodelist.get(2*lastParentIndex+1);
}
// 右孩子,如果數組的長度爲奇數才建立右孩子
else if(array.length%2==1){
nodelist.get(lastParentIndex).left=nodelist.get(2*lastParentIndex+1);
nodelist.get(lastParentIndex).right=nodelist.get(2*lastParentIndex+2);
}
}
/*先序遍歷 */
public static void preOrderTraverse(Node node){//遞歸方式先序輸出
if(node!=null){
System.out.print(node.data+", ");
preOrderTraverse(node.left);
preOrderTraverse(node.right);
}else{
return;
}
}
/** 非遞歸實現先序遍歷 */
protected static void PreOrderTraverse(Node p) {
Stack<Node> stack = new Stack<Node>();
while (p != null) {
if(p.right!=null){
stack.push(p.right);
}
if(p.left!=null){
stack.push(p.left);
}
System.out.print(p.data+", ");
if(!stack.empty()){
p=stack.pop();
}else{
return;
}
}
}
//遞歸方式中序輸出
public static void inOrderTraverse(Node node){
if(node!=null){
inOrderTraverse(node.left);
System.out.print(node.data+", ");
inOrderTraverse(node.right);
}else{
return;
}
}
/** 非遞歸實現中序遍歷 */
protected static void InOrderTraverse(Node p) {
Stack<Node> stack = new Stack<Node>();
while (p != null) {
while (p != null) {
if (p.right != null)
stack.push(p.right);// 當前節點右子入棧
stack.push(p);// 當前節點入棧
p = p.left;
}
p = stack.pop();
while (!stack.empty() && p.right== null) {
System.out.print(p.data+", ");
p = stack.pop();
}
System.out.print(p.data+", ");
if (!stack.empty())
p = stack.pop();
else
p = null;
}
}
//遞歸方式後序輸出
public static void postOrderTraverse(Node node){
if(node!=null){
postOrderTraverse(node.left);
postOrderTraverse(node.right);
System.out.print(node.data+", ");
}else{
return;
}
}
/*
* 非遞歸實現 後序遍歷
* 需要設置一個標籤,標誌該結點是否被訪問過
* 如果該結點被訪問過,則設置其flag值爲true
* */
protected static void PostOrderTraverse(Node p) {
Stack<Node> stack = new Stack<Node>();
while (!p.flag) {//如果節點p被訪問過則設置其flag值爲true
while (!p.flag) {
stack.push(p);// 當前節點入棧
if (p.right != null && !p.right.flag)
stack.push(p.right);// 當前節點右孩子入棧
if (p.left != null && !p.left.flag){
p = p.left; //沿左孩子一直到葉結點
}else{
break;
}
}
p = stack.pop();
while (!stack.empty() && (p.right== null||p.right.flag)&&(p.left== null||p.left.flag)) {
//當棧不空且左右孩子爲空或已訪問,訪問當前結點
System.out.print(p.data+", ");
p.flag=true;
p = stack.pop();
}
if (stack.empty() && p!=null) {//最後輸出根結點
System.out.print(p.data+", ");
p.flag=true;
break;
}
if (stack.empty() && p==null) {
break;
}
}
}
public static void LevelTraverse(Node node){//二叉樹的層次遍歷
Queue<Node> Q=new LinkedList<Node>(); //使用隊列,先進先出
while(node!=null){
if(node.left!=null) //如果左子樹不空,則左子樹入隊
Q.add(node.left);
if(node.right!=null) //如果右子樹不空,則右子樹入隊
Q.add(node.right);
System.out.print(node.data+", ");
node=Q.poll();
}
if(Q.isEmpty()){
return;
}
}
public static void main(String[] args) {
TreeTraverse tree=new TreeTraverse();
tree.creatTree();
Node root=tree.nodelist.get(0);
System.out.print("preOrder: ");
preOrderTraverse(root);
System.out.println();
System.out.print("inOrder: ");
inOrderTraverse(root);
System.out.println();
System.out.print("postOrder: ");
postOrderTraverse(root);
System.out.println();
System.out.print("PreOrder: ");
PreOrderTraverse(root);
System.out.println();
System.out.print("InOrder: ");
InOrderTraverse(root);
System.out.println();
System.out.print("PostOrder: ");
PostOrderTraverse(root);
System.out.println();
System.out.print("Level: ");
LevelTraverse(root);
}
}