二叉树的遍历递归非递归

重点说一下二叉树后序遍历的非递归实现
创建的二叉树如下:

后序遍历为:5 3 2 4 1

先序遍历为:1 2 5 3 4

逆后序遍历为:1 4 2 3 5

从逆后序遍历与先序遍历的关系中我们可以知道逆后序遍历序列为先序遍历交换左右子树的遍历顺序得到的,所以我们得到了逆后序序列之后然后逆序就可以得到后序遍历的序列了,所以需要两个栈,第一个栈用来存储先序遍历交换左右子树的遍历的中介结果,第二个是存储后序遍历的结果(逆序也就是可以理解为先进后出的意思)

下面是模仿元素进栈与出栈的过程:

① 1节点进栈,在循环中弹出1节点压入到第二个栈中,发现左右节点不为空那么将左右节点压入栈1,这个与先序遍历中将左右子树压入到栈顶的顺序是相反的

② 弹出4节点压入到第二个栈中,发现左右孩子都为空那么不进行任何的操作

③ 弹出2节点压入到第二个栈中,发现左右节点不为空那么将左右节点压入到栈1中

④ 弹出3节点压入到第二个栈中,发现左右孩子都为空不进行任何操作

⑤ 弹出5节点压入到第二个栈中,发现左右孩子都为空不进行任何操作

最后栈为空那么退出循环结束
代码:

  1 public class 树的遍历 {
  2     //前序 递归
  3     public static void preOrderTraversal(int[] nums, int i) {
  4         if(i >= nums.length || nums[i] == -1) {
  5             return;
  6         }
  7         System.out.print(nums[i] + " ");
  8         preOrderTraversal(nums, 2 * i + 1);
  9         preOrderTraversal(nums, 2 * i + 2);
 10     }
 11     //前序 非递归
 12     public static void preOrderTraversal2(int[] nums, int i) {
 13         LinkedList<Integer> list = new LinkedList<>();
 14         //i < nums.length && nums[i] != -1表示nums[i]存在
 15         while(i < nums.length && nums[i] != -1 || !list.isEmpty()) {
 16             while(i < nums.length && nums[i] != -1) {
 17                 System.out.print(nums[i] + " ");
 18                 list.push(i);
 19                 i = 2 * i + 1;//nums[i]左节点
 20             }
 21             i = list.pop() * 2 + 2;//nums[i]右节点
 22         }
 23 
 24     }
 25     //中序 递归
 26     public static void inOrderTraversal(int[] nums, int i) {
 27         if(i >= nums.length || nums[i] == -1) {
 28             return;
 29         }
 30         inOrderTraversal(nums, 2 * i + 1);
 31         System.out.print(nums[i] + " ");
 32         inOrderTraversal(nums, 2 * i + 2);
 33     }
 34     //中序 非递归
 35     public static void inOrderTraversal2(int[] nums, int i) {
 36         LinkedList<Integer> list = new LinkedList<>();
 37         while(i < nums.length && nums[i] != -1 || !list.isEmpty()) {
 38             while(i < nums.length && nums[i] != -1) {
 39                 list.push(i);
 40                 i = 2 * i + 1;
 41             }
 42             int k = list.pop();
 43             System.out.print(nums[k] + " ");
 44             i = k * 2 + 2;
 45         }
 46     }
 47 
 48     //后序 递归
 49     public static void postOrderTraversal(int[] nums, int i) {
 50         if(i >= nums.length || nums[i] == -1) {
 51             return;
 52         }
 53         postOrderTraversal(nums, 2 * i + 1);
 54         System.out.print(nums[i] + " ");
 55         postOrderTraversal(nums, 2 * i + 2);
 56 
 57     }
 58     
 59     //后续 非递归 双栈
 60     public static void postOrderTraversal2(int[] nums, int i) {
 61         LinkedList<Integer> stack1 = new LinkedList<>();
 62         LinkedList<Integer> stack2 = new LinkedList<>();
 63         stack1.push(i);
 64         while (!stack1.isEmpty()) {
 65             i = stack1.pop();
 66             stack2.push(i);//把stack1栈顶的元素压进list中
 67             i = 2 * i + 1;
 68             if(i < nums.length && nums[i] != -1)
 69                stack1.push(i);
 70             ++i;
 71             if(i < nums.length && nums[i] != -1)
 72                 stack1.push(i);
 73         }
 74         for (int k: stack2) {
 75             System.out.print(nums[k] + " ");
 76         }
 77 
 78     }
 79 
 80     //层序遍历 队列实现
 81     public static void levelOrder(int[] nums, int i) {
 82         LinkedList<Integer> que = new LinkedList<>();
 83         que.push(i);
 84         while(!que.isEmpty()) {
 85             i = que.removeFirst();
 86             System.out.print(nums[i] + " ");
 87             i = 2 * i + 1;
 88             if(i < nums.length && nums[i] != -1)
 89                 que.addLast(i);
 90             ++i;
 91             if(i < nums.length && nums[i] != -1)
 92                 que.addLast(i);
 93         }
 94     }
 95 
 96     public static void main(String[] args) {
 97         int[] nums = new int[]{1, 2, 3, -1, 5, 6, -1};
 98         postOrderTraversal2(nums, 0);
 99     }
100 }

 

  

posted @ 2020-09-08 14:58  看完这篇还有亿篇  阅读(160)  评论(0编辑  收藏  举报