節點類:
public class Node <T>{
public T data;
public Node<T> left = null;
public Node<T> right = null;
public Node(T data) {
super();
this.data = data;
}
}
先根遍歷:先訪問根節點元素,然再訪問左右子樹節點
/**
* 遞歸方法
* @param root
*/
public <T> void traverse(Node<T> root){
if(root == null){
return ;
}
out.println(root.data);
traverse(root.left);
traverse(root.right);
}
/**
* 非遞歸方法,利用LinkedList模擬函數棧
* @param root
*/
public <T> void traverse2(Node<T> root){
LinkedList<Node<T>> list = new LinkedList<>();
list.push(root);
while(list.size()>0){
Node<T> now = list.pop();
if(now==null){
continue;
}
out.println(now.data);
list.push(now.right);//先添加右節點再添加左節點確保左節點先被訪問
list.push(now.left);
}
}
}
中根遍歷
package binaryTree;
import java.io.PrintStream;
import java.util.LinkedList;
import org.junit.Test;
public class InorderTraversal {
protected PrintStream out =null;
public void setOut(PrintStream out) {
this.out = out;
}
/**
* 遞歸方法
* @param root
*/
public <T> void traverse(Node<T> root){
if(root == null){
return ;
}
traverse(root.left);
out.println(root.data);
traverse(root.right);
}
/**
* 非遞歸方法,利用2個LinkedList模擬遍歷過程,第一個棧中存放第二個棧頂元素的左節點,第一個棧空,說明第二個棧頂元素左節點訪問完畢
* @param root
*/
public <T> void traverse2(Node<T> root){
LinkedList<Node<T>> first = new LinkedList<>();
LinkedList<Node<T>> secend = new LinkedList<>();
first.push(root);
while(first.size()>0||secend.size()>0){
if(first.size()==0){
Node<T> now = secend.removeLast();
out.println(now.data);
if(now.right!=null){
first.push(now.right);
}
continue;
}
Node<T> now = first.pop();
secend.add(now);
if(now.left!=null){
first.add(now.left);
}
}
}
/**
* 非遞歸方法,利用LinkedList模擬棧,now指向stack棧頂元素的左子樹,now指向空,說明棧頂元素左子樹訪問完畢
* @param root
*/
public <T> void traverse3(Node<T> root){
LinkedList<Node<T>> stack = new LinkedList<>();
Node<T> now = root;
while(now!=null||stack.size()>0){
if(now==null){
now = stack.pop();
out.println(now.data);
now=now.right;
}else{
stack.push(now);
now = now.left;
}
}
}
}
後根遍歷:
package binaryTree;
import java.io.PrintStream;
import java.util.LinkedList;
import org.junit.Test;
public class PostorderTraversal {
protected PrintStream out =null;
public void setOut(PrintStream out) {
this.out = out;
}
/**
* 遞歸方法
* @param root
*/
public <T> void traverse(Node<T> root){
if(root == null){
return ;
}
traverse(root.left);
traverse(root.right);
out.println(root.data);
}
/**
* 非遞歸方法,利用兩個指針,stack中記錄訪問過的節點
* @param root
*/
public <T> void traverse2(Node<T> root){
LinkedList<Node<T>> stack = new LinkedList<>();
Node<T> now ;
Node<T> pre = null;
stack.push(root);
while(stack.size()>0){
now = stack.peek();
if((now.left==null&&now.right==null)||
( pre!=null&&(pre==now.left||pre==now.right)) ){//now沒有子節點或者上次訪問的節點是now的子節點
out.println(now.data);
stack.pop();
pre = now;
}else{
if(now.right!=null){
stack.push(now.right);
}
if(now.left!=null){
stack.push(now.left);
}
}
}
}
}
層次遍歷:
package binaryTree;
import java.io.PrintStream;
import java.util.LinkedList;
import org.junit.Test;
public class LevelTraversal {
protected PrintStream out =null;
public void setOut(PrintStream out) {
this.out = out;
}
/**
* 非遞歸方法,利用LinkedList模擬隊列,很簡單
* @param root
*/
public <T> void traverse(Node<T> root){
LinkedList<Node<T>> queue = new LinkedList<>();
Node<T> now ;
queue.offer(root);
while(queue.size()>0){
now = queue.poll();
out.println(now.data);
if(now.left!=null) queue.add(now.left);
if(now.right!=null) queue.add(now.right);
}
}
}
測試函數:
@Test
public void test(){
Node<Integer> root1 = new Node<Integer>(1);
Node<Integer> root2 = new Node<Integer>(2);
Node<Integer> root3 = new Node<Integer>(3);
Node<Integer> root4 = new Node<Integer>(4);
Node<Integer> root5 = new Node<Integer>(5);
Node<Integer> root6 = new Node<Integer>(6);
Node<Integer> root7 = new Node<Integer>(7);
this.out = System.out;
root1.left = root2;
root1.right = root5;
root2.left = root3;
root2.right = root4;
root5.left = root6;
root5.right = root7;
traverse(root1);
}