递归的3种方式
遍历一棵树和遍历一颗顺序存储的二叉树数组结果是一样的,因此,这里使用顺序存储的二叉树数组来写这个代码
同理
下面介绍一下非递归的遍历方法
先看先序遍历的代码:
public static void preOrder()
{
int[] arr = {1,2,3,4,5,6,7};
Stack<Integer> stack = new Stack<Integer>();
stack.push(0);
while(!stack.isEmpty())
{
int cur = stack.pop();
System.out.print(arr[cur]+" ");
int right = cur*2+2;
int left = cur*2 + 1;
if(right<arr.length)
{
stack.push(right);
}
if(left<arr.length)
{
stack.push(left);
}
}
*这是大概的样子 *
这是先序遍历的样子
***先压右边子树 ,再压左子树 ***
下一次出栈的时候,就是左子树的节点弹出栈,然后让其子树的右节点入栈,再让其子树的左节点入栈
也就是说,我们始终把左节点面对着栈顶,右节点压到栈底
这就是非递归先序遍历这奇怪的代码的逻辑
先序遍历还有一种写法
推荐用过这种,容易记
public static void preorder2()
{
int[] arr = {5,3,7,2,4,6,8};
Stack<Integer> stack = new Stack<Integer>();
int i=0;
while((!stack.isEmpty())||i<arr.length)
{
while(i<arr.length)
{
System.out.println(arr[i]);
stack.push(i);
i=i*2+1;
}
if(!stack.isEmpty())
{
i=stack.pop();
i=i*2+2;
}
}
}
下面给出二叉树中序遍历存储二叉树的数组的代码
public static void InOrder()
{
int[] arr = {5,3,7,2,4,6,8};
Stack<Integer> stack = new Stack<Integer>();
int i=0;
while(!stack.isEmpty()||i<arr.length)
{
while (i<arr.length)
{
stack.push(i);
i = i*2+1;
}
if(!stack.isEmpty())
{
i = stack.pop();
System.out.println(arr[i]);
i = i*2+2;
}
}
}
后序遍历
额,栈可以做了,但是还不如队列呢
对于后序遍历和层序遍历可以使用队列来做
public static void postOrder()
{
// 因为在后序遍历中,要保证左孩子和右孩子都已被访问并且左孩子在右孩子前访问才能访问根结点
int[] arr = {5,3,7,2,4,6,8};
LinkedList<Integer> deque = new LinkedList();
LinkedList<Integer> ans = new LinkedList();
deque.addLast(0);
while (deque.size()!=0)
{
int i = deque.pollLast();
ans.addFirst(arr[i]);
int l = i*2+1;
int r = l+1;
if(l<arr.length)
{
deque.add(l);
}
if(r<arr.length)
{
deque.add(r);
}
}
for (Integer i : ans) {
System.out.print(i+" ");
}
}