二叉树的所有遍历完整实现
程序员文章站
2022-05-06 22:53:34
...
import java.util.*;
//结点定义
class TreeNode {
int data;
TreeNode left, right;
public TreeNode(int data) {
this.data = data;
this.left = null;
this.right = null;
}
}
//测试
public class Solution {
public static void main(String args[]) {
int preOrder[] = new int[]{4, 2, 1, 3, 5, 6};
int inOrder[] = new int[]{1, 2, 3, 4, 5, 6};
//调用建树的函数
Solution s = new Solution();
TreeNode root = s.buildTree(preOrder, 0, preOrder.length - 1, inOrder, 0, inOrder.length - 1);
System.out.print("前序递归是:");
s. preTravel_1(root);
System.out.println();
System.out.print("中序递归是:");
s. inTravel_1(root);
System.out.println();
System.out.print("后序递归是:");
s. postTravel_1(root);
System.out.println();
System.out.print("层次遍历是:");
s.levelTravle(root);
System.out.println();
System.out.print("前序非递归是:");
s. preTravel_2(root);
System.out.println();
System.out.print("中序非递归是:");
s. inTravel_2(root);
System.out.println();
System.out.print("后序非递归是:");
s. postTravel_2(root);
System.out.println();
}
//根据前序和中序建立一颗二叉树
public TreeNode buildTree(int preOrder[], int preStart, int preEnd, int inOrder[], int inStart, int inEnd) {
//根节点
TreeNode root = new TreeNode(preOrder[preStart]);
//空树,递归出口
if (preStart == preEnd || inStart == inEnd)
return root;
if (preStart > preEnd || inStart > inEnd)
return null;
//找到根节点在中序中的位置,以便划分成两部分
int loc = locateRoot(preOrder[preStart], inOrder);
root.left = buildTree(preOrder, preStart + 1, loc - inStart + preStart, inOrder, inStart, loc - 1);
root.right = buildTree(preOrder, loc - inStart + preStart + 1, preEnd, inOrder, loc + 1, inEnd);
return root;
}
//找到结点在中序遍历的位置
public int locateRoot(int key, int inOrder[]) {
for (int i = 0; i < inOrder.length; i++)
if (inOrder[i] == key)
return i;
return -1;
}
//中序递归
//前序递归
public void preTravel_1(TreeNode root) {
if (root == null)
return;
System.out.print(root.data+" ");
preTravel_1(root.left);
preTravel_1(root.right);
}
//中序递归
public void inTravel_1(TreeNode root){
if(root==null)
return;
inTravel_1(root.left);
System.out.print(root.data+" ");
inTravel_1(root.right);
}
//后序递归
public void postTravel_1(TreeNode root){
if(root==null)
return ;
postTravel_1(root.left);
postTravel_1(root.right);
System.out.print(root.data+" ");
}
//层次遍历,借助队列
public void levelTravle(TreeNode root){
if(root==null)
return;
Queue<TreeNode> queue=new LinkedList<>();
queue.offer(root);
TreeNode cur=root;
while(!queue.isEmpty()){
int n=queue.size();
for(int i=0;i<n;i++){
cur = queue.poll();
System.out.print(cur.data+" ");
if(cur.left!=null)
queue.offer(cur.left);
if(cur.right!=null)
queue.offer(cur.right);
}
}
}
//前序非递归
public void preTravel_2(TreeNode root){
if(root==null)
return ;
Stack<TreeNode>stack =new Stack<>();
TreeNode cur=root;
stack.push(cur);
while(!stack.isEmpty()){
cur=stack.pop();
System.out.print(cur.data+" ");
if(cur.right!=null){
stack.push(cur.right);
}
if(cur.left!=null){
stack.push(cur.left);
}
}
}
//中序非递归
public void inTravel_2(TreeNode root){
if(root==null)
return ;
Stack<TreeNode> stack =new Stack<>();
TreeNode cur=root;
while(!stack.empty()||cur!=null){
//先找到最左边的孩子,所有左孩子一次入栈
while(cur!=null){
stack.push(cur);
cur=cur.left;
}
//最左边的孩子
cur=stack.pop();
System.out.print(cur.data+" ");
cur=cur.right;
}
}
//后序非递归,这个最难,最好记下来
public void postTravel_2(TreeNode root){
if(root==null)
return;
Stack<TreeNode> stack=new Stack<>();
TreeNode cur=root;
TreeNode pre=null;
while(!stack.isEmpty()||cur!=null){
//找到最左边的孩子
while(cur!=null){
stack.push(cur);
cur=cur.left;
}
//判断最左边的孩子没有右子树,或者右子树已被访问
cur=stack.peek();
if(cur.right==null||cur.right==pre){
System.out.print(cur.data+" ");
pre=stack.pop();
cur=null; //结束条件
}else
cur=cur.right;
}
} //end
}
上一篇: Struts2 简单数据验证
下一篇: 记录一次重构