关于二叉树的前序、中序、后序三种遍历(递归与非递归)

二叉树遍历分为三种:前序、中序、后序,其中序遍历最为重要。为啥叫这个名字?是根据根节点的顺序命名的。

比如上图正常的一个满节点,A:根节点、B:左节点、C:右节点,前序顺序是ABC(根节点排最先,然后同级先左后右);中序顺序是BAC(先左后根最后右);后序顺序是BCA(先左后右最后根)。

    

比如上图二叉树遍历结果

    前序遍历:ABCDEFGHK

    中序遍历:BDCAEHGKF

    后序遍历:DCBHKGFEA

分析中序遍历如下图,中序比较重要(java很多树排序是基于中序,后面讲解分析)

 

代码如下:

public class BinaryTree {
int data;
BinaryTree left;
BinaryTree right;

@Override
public String toString() {
return "BinaryTree{" +
"data=" + data +
'}';
}

public BinaryTree(int data) {
this.data = data;
left = null;
right = null;
}

public BinaryTree(){}

//插入数据
public void insert(BinaryTree root, int data) {
//判断数据是否比当前节点值大
if (data > root.data) {
//如果右节点为null先创建对象,并赋值
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 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 preOrderNoRecursion(BinaryTree root) {
System.out.println("非递归先序遍历:");
LinkedList<BinaryTree> stack = new LinkedList<BinaryTree>();
stack.push(root);
BinaryTree current = null;
while (!stack.isEmpty()) {
current = stack.pop();
System.out.print(current.data + "_");
if (current.right != null) {
stack.push(current.right);
}
if (current.left != null) {
stack.push(current.left);
}
}
}

public static void inOrderNoRecursion(BinaryTree root) {
System.out.println("非递归中序遍历:");
LinkedList<BinaryTree> stack = new LinkedList<BinaryTree>();
BinaryTree current = root;
while (current != null || !stack.isEmpty()) {
while (current != null) {
stack.push(current);
current = current.left;
}
if (!stack.isEmpty()) {
current = stack.pop();
System.out.print(current.data + "_");
current = current.right;
}
}
}

public static void postOrderNoRecursion(BinaryTree root) {
System.out.println("非递归后序遍历:");
LinkedList<BinaryTree> stack = new LinkedList<BinaryTree>();
BinaryTree current = root;
BinaryTree rNode = null;
while (current != null || !stack.isEmpty()) {
//判断左节点是否为空
while (current != null) {
//存放左节点(当前节点)
stack.push(current);
current = current.left;
}
//取出放入的最后一个节点为当前节点
current = stack.pop();

//判断当前节点是否为空,并且当前节点右节点为null
while (current != null && (current.right == null || current.right == rNode)) {
//输出当前节点值
System.out.print(current.data + "-");
rNode = current;
if (stack.isEmpty()) return;
//再取出一个节点为当前节点
current = stack.pop();
}
stack.push(current);
current = current.right;
}
}

public static void levelOrder(BinaryTree root) {
if (root == null) return;
Queue<BinaryTree> q = new LinkedList<BinaryTree>();
q.add(root);
while (q != null) {
BinaryTree temp = q.poll();
System.out.print(temp.data + "_");
if (temp.left != null) q.add(temp.left);
if (temp.right != null) q.add(temp.right);
}
}

//二叉树最大深度
public static int maxDepth(BinaryTree root) {
if(root==null){
return 0;
}
return 1+Math.max(maxDepth(root.left),maxDepth(root.right));
}

//二叉树节点个数
public static int getNodenum(BinaryTree root) {
if(root==null){
return 0;
}
return getNodenum(root.left) + getNodenum(root.right) +1;
}


//二叉树中叶子节点的个数
static int GetLeafNodeNum(BinaryTree root) {
if(root == null) return 0;
if (root.left == null && root.right ==null) return 1;
int left_num = GetLeafNodeNum(root.left);
int right_num = GetLeafNodeNum(root.right);
return left_num + right_num;
}

public static void main(String[] args) {
int[] array = { 55, 76, 35, 22,23,16, 17,48, 90, 46,75, 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);
// System.out.println("非递归后根遍历:");
// postOrderNoRecursion(root);
}

}
posted @ 2019-04-11 23:00  Zuul  阅读(337)  评论(0编辑  收藏  举报