以下程序测试使用的二叉树:
前序遍历序列:1 2 3 6 8 9 7
中序遍历序列:2 1 6 9 8 3 7
后序遍历序列:2 9 8 6 7 3 1
层序遍历序列:1 2 3 6 7 8 9
二叉树类型定义和访问函数
【1. 前序遍历-递归】
也可以叫深度遍历,先访问根节点,再依次访问其左、右子树。
【2.1 前序遍历-非递归】
需要用到栈。根节点先入栈,当栈不为空循环,依次取出栈顶结点,访问,将其右、左子树依次入栈。注意要先将右子树入栈,后将左子树入栈,这样在出栈时,先访问左边。
【2.2 前序遍历-非递归】
先将根节点入栈,如果栈不为空,循环:向左走到头,沿途访问结点并入栈,直到最左结点,出栈一个结点,将其右子树入栈。
【3. 中序遍历-递归】
先访问左子树,再访问根结点,最后访问右子树。
【4.1 中序遍历-非递归】
如果结点不为空或栈不为空,循环:如果结点不为空,入栈,下一次查看其左子树(沿着左边一直往下,直到其最左结点);如果结点为空,出栈一个结点,访问此结点,下一次查看其右子树。
如果结点为空:
-当前结点是一个左子树结点,此NULL结点的父结点其实没有左子树,将父节点出栈,访问父节点(左子树已完成),接着查看父节点的右子树,右子树并未入栈。
-当前结点是一个右子树结点,此NULL结点的父结点其实没有右子树,此时栈顶是父节点的父节点,代表父节点为根的树遍历完成了,出栈,接着查看父节点的父节点的右子树。
【4.2 中序遍历-非递归】
与【2.2 前序遍历-非递归】几乎一摸一样,除了Visit() 调用的位置。
【5. 后序遍历-递归】
先遍历左子树,再遍历右子树,最后访问根结点。
【5.1 后序遍历-非递归】
根节点入栈,如栈不为空,循环:last记住刚访问过的结点;第二个if,将树上所有的节点都按根、右、左的次序入栈;第一个if,如果是last == node->lChild,而由于入栈顺序是根右左,说明node没有右子树,接下来该访问根了;如果是last == node->rChild,说明node的左右子树都访问完了,根据后序遍历的定义,接下来该访问根了。
【5.2 后序遍历-非递归】
这个很难理解。。。
【6. 层序遍历】
也叫广度遍历,使用队列实现。