**二叉树的前序遍历,中序遍历,后序遍历(递归实现和非递归实现) **
中序遍历非递归实现
递归遍历的实质:就是在第几次来打印出读取到的数字,递归树中每个数字读取到三次 前序遍历就是第一次读取到就打印出来 中序遍历就是第二次遍历到就打印出来 后序遍历就是第三次遍历到就打印出来
先序遍历的非递归实现
后序遍历的非递归实现
```bash
public class BinaryTree {
//前三个方法递归实现 前中后序的遍历
public static void preOrderRecur(TreeNode root){
if (root==null){
return;
}
System.out.println(root.val+"");
preOrderRecur(root.left);
preOrderRecur(root.right);
}
public static void inOrderRecur(TreeNode root){
if (root==null){
return;
}
inOrderRecur(root.left);
System.out.println(root.val+"");
inOrderRecur(root.right);
}
public static void postOrderRecur(TreeNode root){
if (root==null){
return;
}
postOrderRecur(root.left);
postOrderRecur(root.right);
System.out.println(root.val+"");
}
//后三种方法非递归实现 递归实现只是虚拟机栈帮助我们压站出站 我们可以自己动手实现压站出站
//对于先序遍历 固定流程:每次1.从栈中弹出一个节点
// 2.打印弹出栈的节点
// 3.先右边后左边的压入栈中
// 4.循环第一步骤
public static void preOrderUnRecur(TreeNode root){
System.out.println("pre-order:");
if (root!=null){
Stack<TreeNode> stack = new Stack<>();
stack.add(root);
while (!stack.isEmpty()){
TreeNode head = stack.pop();
System.out.println(head.val+"");
if (head.right!=null){
stack.push(head.right);
}
if (head.left!=null){
stack.push(head.left);
}
}
}
}
//中序遍历 每棵子树的,整棵树的左边界进栈,依次弹出的过程中,打印,并将弹出节点的右子树重复同样的步骤
public static void inOrderUnRecur(TreeNode root){
System.out.println("in-order");
if (root!=null){
Stack<TreeNode> stack = new Stack<>();
while (!stack.isEmpty()||root!=null){
if (root!=null){
stack.push(root);
root=root.left;
}
else {
root=stack.pop();
System.out.println(root.val+"");
root=root.right;
}
}
stack.add(root);
}
}
//对于后序遍历:1,需要两个栈 一个栈用来弹栈 一个栈用来收栈
// 2,读取根放入弹栈中 弹出后
// 3, 放入收栈中
// 4,先左后右读取放入弹栈中
// 5,循环2步骤
// 6,最后的读取收栈中的元素 一次弹栈 读取数值 即为所读取到的后序遍历
public static void postOrderUnRecur(TreeNode root){
System.out.println("pos-order");
if (root!=null){
Stack<TreeNode> s1= new Stack<>();
Stack<TreeNode> s2= new Stack<>();
s1.push(root);
while (!s1.isEmpty()){
TreeNode head = s1.pop();
s2.push(head);
if (head.left!=null){
s1.push(head.left);
}
if (head.right!=null){
s1.push(head.right);
}
}
while (!s2.isEmpty()){
System.out.println(s2.pop().val+"");
}
}
}
public static void main(String[] args) {
TreeNode root= new TreeNode(5);
TreeNode treeNode1 = new TreeNode(3);
TreeNode treeNode2= new TreeNode(1);
TreeNode treeNode3 = new TreeNode(2);
TreeNode treeNode4= new TreeNode(6);
root.left=treeNode1;
root.right=treeNode3;
treeNode1.left=treeNode2;
treeNode3.right=treeNode4;
preOrderRecur(root);
System.out.println("======================");
inOrderRecur(root);
System.out.println("======================");
postOrderRecur(root);
System.out.println("======================");
preOrderUnRecur(root);
System.out.println("======================");
inOrderUnRecur(root);
System.out.println("======================");
postOrderUnRecur(root);
}
}
二叉树的前序遍历就是深度优先遍历
下面讲的是宽度优先遍历
进行宽度优先遍历并找到最大的宽度
主要是在遍历的过程中记录每层的宽度 取最大值
//层序遍历
public static void w(TreeNode root){
if(root==null){
return;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()){
TreeNode cur = queue.poll();
System.out.println(cur.val);
if (cur.left!=null){
queue.add(cur.left);
}
if (cur.right!=null){
queue.add(cur.right);
}
}
}
//求最大宽度
public static void w_num(TreeNode root){
if(root==null){
return;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
HashMap<TreeNode, Integer> levelMap = new HashMap<>();
levelMap.put(root,1);
int curLevel=1;
int curLevelNodes=0;
int max=Integer.MIN_VALUE;
while (!queue.isEmpty()){
TreeNode cur = queue.poll();
int curNodeLevel = levelMap.get(cur);
if (curLevel==curNodeLevel){
curLevelNodes++;
}
else {
max=Math.max(max,curLevelNodes);
curLevel++;
curLevelNodes=1;
}
if (cur.left!=null){
levelMap.put(cur.left,curNodeLevel+1);
queue.add(cur.left);
}
if (cur.right!=null){
levelMap.put(cur.right,curNodeLevel+1);
queue.add(cur.right);
}
}
System.out.println(max);
}