最近在研究数据结构算法,发现许多树类的算法都很灵活,所以研究了一下基础二叉树的递归以及非递归的三种遍历方式,在这里记录下来方便以后回忆。
以该树为例:
二叉树的遍历为三种:前序遍历、中序遍历、后续遍历。
前序遍历(先根遍历):即是在二叉树的遍历过程中,先访问根节点若左子树不空则访问左节点、若右子树不空则访问右节点,在访问左右子树时亦是先访问根节点再访问左节点、右节点,以此顺序。
此树的先序遍历结果为: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);
}
}
原帖地址为: