最近在研究數據結構算法,發現許多樹類的算法都很靈活,所以研究了一下基礎二叉樹的遞歸以及非遞歸的三種遍歷方式,在這裏記錄下來方便以後回憶。
以該樹爲例:
二叉樹的遍歷爲三種:前序遍歷、中序遍歷、後續遍歷。
前序遍歷(先根遍歷):即是在二叉樹的遍歷過程中,先訪問根節點若左子樹不空則訪問左節點、若右子樹不空則訪問右節點,在訪問左右子樹時亦是先訪問根節點再訪問左節點、右節點,以此順序。
此樹的先序遍歷結果爲:631254978
中序遍歷(中跟遍歷):即是先訪問左節點,再根節點,最後右節點。
中序遍歷結果爲:123456789
後序遍歷(後跟遍歷):先訪問左節點,再右節點、最後根節點。
後序遍歷結果爲:214538796
1、遞歸方式
建立數據模型()
public class Node {//二叉樹節點
private int data;
private Node leftNode;
private Node rightNode;
public Node(int data, Node leftNode, Node rightNode){
this.data = data;
this.leftNode = leftNode;
this.rightNode = rightNode;
}
public int getData(){
return data;
}
public void setData(int data){
this.data = data;
}
public Node getLeftNode(){
return leftNode;
}
public void setLeftNode(Node leftNode){
this.leftNode = leftNode;
}
public Node getRightNode(){
return rightNode;
}
public void setRightNode(Node rightNode){
this.rightNode = rightNode;
}
}
三種遍歷:
package Binary_tree;
public class Traverse_tree {
/*
* 二叉樹先序中序後序排序
* 方式:遞歸。
*/
//注意必須逆序簡歷,先建立子節點,再逆序往上建立,
//因爲非葉子節點會使用到下面的節點,而初始化是按順序初始化得,不逆序建立會報錯
public static Node init(){
Node J = new Node(8, null, null);
Node H = new Node(4, null, null);
Node G = new Node(2, null, null);
Node F = new Node(7, null, J);
Node E = new Node(5, H, null);
Node D = new Node(1, null, G);
Node C = new Node(9, F, null);
Node B = new Node(3, D, E);
Node A = new Node(6, B, C);
return A; //返回根節點
}
//打印節點數值
public static void printNode(Node node){
System.out.print(node.getData());
}
public void preOrder(Node root){ //前序遍歷
printNode(root);
if(root.getLeftNode()!=null)
preOrder(root.getLeftNode());
if(root.getRightNode()!=null)
preOrder(root.getRightNode());
}
public void inOrder(Node root){ //中序遍歷
if(root.getLeftNode()!=null)
inOrder(root.getLeftNode());
printNode(root);
if(root.getRightNode()!=null)
inOrder(root.getRightNode());
}
public void postOrder(Node root){ //後續遍歷
if(root.getLeftNode()!=null)
postOrder(root.getLeftNode());
if(root.getRightNode()!=null)
postOrder(root.getRightNode());
printNode(root);
}
public static void main(String[] args){
Node node = Traverse_tree.init();
Traverse_tree obj = new Traverse_tree();
System.out.println("前序遍歷");
obj.preOrder(node);
System.out.println();
System.out.println("中序遍歷");
obj.inOrder(node);
System.out.println();
System.out.println("後續遍歷");
obj.postOrder(node);
}
}
2、非遞歸的三種遍歷方式:
import java.util.Stack;
public class Nontraverse_tree {
Node node;
public static Node_Nontraverse init(){
Node I = new Node(8,null,null);
Node H = new Node(4,null,null);
Node G = new Node(2,null,null);
Node D = new Node(1,null,G);
Node E = new Node(5,H,null);
Node F = new Node(7,null,I);
Node B = new Node(3,D,E);
Node C = new Node(9,F,null);
Node A = new Node(6,B,C);
return A;
}
public void preOrder(Node node){
Node root = node;
Stack<Node> stack = new Stack<Node>();
while(root!=null||stack.size()>0){
if(root!=null){
stack.push(root);
System.out.print(root.getData());
root = root.getLeftNode();
}
else{
root = stack.pop();
root = root.getRightNode();
}
}
}
public void inOrder(Node node){
Node root = node;
Stack<Node> stack = new Stack<Node>();
while(root!=null||stack.size()>0){
if(root!=null){
stack.push(root);
root = root.getLeftNode();
}
else{
root = stack.pop();
System.out.print(root.getData());
root = root.getRightNode();
}
}
}
public void postOrder(Node node){
Node root = node;
Stack<Node> stack = new Stack<Node>();
Stack<Node> output = new Stack<Node>();
while(root!=null||stack.size()>0){
if(root!=null){
stack.push(root);
output.push(root);
root = root.getRightNode();
}
else{
root = stack.pop();
root = root.getLeftNode();
}
}
while(output.size()>0){
System.out.print(output.pop().getData());
}
}
public static void main(String[] args){
Nontraverse_tree obj = new Nontraverse_tree();
Node root = Nontraverse_tree.init();
System.out.println("二叉樹的非遞歸前序遍歷:");
obj.preOrder(root);
System.out.println();
System.out.println("二叉樹的非遞歸中序遍歷:");
obj.inOrder(root);
System.out.println();
System.out.println("二叉樹的非遞歸後序遍歷:");
obj.postOrder(root);
}
}
原帖地址爲: