二叉树的递归遍历很简单,就不详述了。而非递归遍历有一定的难度,所以专门写一篇文章来总结这三种非递归遍历。废话不多说,直接进入正题
在讲非递归遍历之前,先讲一下栈,这是非递归算法的核心思想。
如图:
栈是后进先出,先进后出,我想既然大家都学到二叉树了,那么栈肯定也不陌生,我主要想加深大家对栈的理解。
试想,你在浏览网页的时候,突然发现了一个有趣的链接,你点击进去,发现原来是广告,于是你想退回到上一个网页,那么点击浏览器上方的后退图标就很轻松地退回去了。
那么,你点击一个网页,再点击一个网页,就是个进栈的过程,你点击后退,就是出栈的过程。那么,是不是离你最近的网页最先被后退掉呢?这就是后进先出。
在这个例子中,浏览器把之前的网页 保存 了,也即放到栈内,以后我们就可以通过出栈的方式找到它。
综上,就引出了,栈的存储功能。
那么,再来深化一下栈的操作。当栈为空时,top的值为-1,每入栈一次,top的值便加1,每出栈一次,top的值便-1。本质上就是通过修改数组的下标来实现出栈和入栈。
好了,现在让我们步入正题吧。
我打算从易到难讲起。
假设有如下图所示的一棵二叉树:
先从先序遍历讲起。
我们知道,先序遍历的顺序是ABDECFG。若想用非递归实现可以通过一个指针p,先让它指向根节点A,再指向B…
然后再那么问题就来了,指针指向D时,让D出栈,然后呢,E子节点怎么访问?C怎么访问?F和G呢?你说:“再让指针p指向B不就行了?”那你保存了指针B的值了吗?你现在还能找得到么?
所以说,问题的关键就在于我们得保存节点,即有指针指向该节点。而这明显是栈的情况,即后进先出。于是,我们可以想到,用一个数组,存放这几个指针,也即要声明一个指针数组。
代码如下:
void preorderTraverse1(BiTree *Tree){
BiTree *a[20];
BiTree *p;
p=