今天中午,看到论坛上有人求用C++实现创建二叉树,以及用栈的操作(非递归)实现对该二叉树的前、中、后三种遍历。刚好自己复习了一下二叉树,就帮忙写写吧。也算练练笔吧。
创建二叉树的设计:输入的时候是以数组的形式输进去的,然后通过void initBiTree(pNode & biTree, int iniArr[], int pos)函数建立二叉树。建立二叉树是利用递归建立的,每建完一个节点,在建立左节点和有节点之前,先判断该节点是否为空,如果为空则返回,否则就创建该节点的左右子节点。
前序遍历二叉树:这个比较简单,主要思想就是每访问完一个节点之后,就把该节点的右子节点和左子节点依次压入栈中。
中序遍历二叉树:比前序稍微难一点,首先把根节点压入栈中,进入循环,利用一个内部的嵌套循环遍历左节点,并把所有得到的左节点都压入栈中,直到空栈的时候,pop出一个空节点,然后在访问top,并将其pop掉,之后在得到一个新的top,并将该top的右节点压入栈中,然后再回到循环
后序遍历二叉树:这个相对来说是最难的,我也分析了蛮久才写出来的,伪代码如下:
1、初始化两个节点top,child都为NULL,top为当前的栈顶,child为上次访问过的节点
2、 在根节点不为空的情况下,首先压入根节点;
3、while(栈不为空)
{
3.1 获取栈的top节点
3.2 if(top->lchild和top->rchild都为NULL),说明到了一个终节点,于是visit(top)然后设置child=top,pop掉top;并continue;
3.3 if(top->lchild等于child),说明top的左子树已经被访问过,因此要判断是有子树是否为空,如果不为空,则压入栈中,否则visit(top),并 设置child=top,pop掉top
3.4else if( top->rchild等于child ), 说明top的右子树已经被访问过,因此,下一个访问的必定为top节点,于是直接visit(top), 并 设置 child=top,pop掉top
3.5else(child并不是top的左子树,也不是child的右子树),说明top这棵树还没有被访问过,于是
3.5.1while(top->lchild不等于NULL)
{
将top->lchild压入栈中,并设置top = top->lchild;
}
}
具体代码如下,并没有写释放内存的函数:
测试数据如下:
开始输入的是一个整形数组,注意数组的输入一定要可以构成二叉树,否者只构造能形成二叉树的部分。
第一个输入代表数组的个数,0表示空
例如:
6
1 2 3 4 5 6
前序遍历结果:
1 2 4 5 3 6
中序遍历结果:
4 2 5 1 6 3
后序遍历结果:
4 5 2 6 3 1
11
1 2 3 0 4 5 6 0 0 7 8
前序遍历结果:
1 2 4 7 8 3 5 6
中序遍历结果:
2 7 4 8 1 5 3 6
后序遍历结果:
7 8 4 2 5 6 3 1