由于递归容易导致栈溢出,所以我们采用非递归进行处理
非递归采用 循环和栈 的方式进行处理
一、前序
//前序 void PreOrderLoop(TreeNode *pRoot) { TreeNode *pCur = pRoot; Stack stack; //定义一个栈 TreeNode *pTop; //栈顶元素 stackInit(&stack); while (!stackIsempty(&stack) || pCur != NULL) //循环条件 { while (pCur != NULL) { printf("%c ", pCur->data); //打印结点数据 stackPush(&stack, pCur); //进行入栈 pCur = pCur->pleft; //再去遍历他的左子树 } pTop = stackTop(&stack); //循环退出 左子树全部遍历完 stackPop(&stack); //将栈顶元素出栈 pCur = pTop->pright; //再去遍历此时根的左子树 } }二、中序
//中序 void InOrderLoop(TreeNode *pRoot) { TreeNode *pCur = pRoot; Stack stack; TreeNode *pTop; stackInit(&stack); while (!stackIsempty(&stack) || pCur != NULL) { while (pCur != NULL) { stackPush(&stack, pCur); pCur = pCur->pleft; } pTop = stackTop(&stack); stackPop(&stack); printf("%c ", pTop->data); pCur = pTop->pright; } }
三、后序
后序这里我们要考虑的比前面两个多一点,首先:我们会定义一个plast变量来表示上一次已经被后序遍历完的根
我们打印的条件分为两种:(1)右子树为空 (2)右子树已经被遍历
若符合则进行打印,否则遍历此结点的右子树
代码如下~
//后序 void PostOrderLoop(TreeNode *pRoot) { TreeNode *pCur = pRoot; Stack stack; TreeNode *pTop=NULL; TreeNode *plast = NULL; //表示上一次已经被后序遍历完的树的根 stackInit(&stack); while (!stackIsempty(&stack) || pCur != NULL) { while (pCur != NULL) { stackPush(&stack, pCur); pCur = pCur->pleft; } //没有被遍历的 还剩栈里的右子树和根 pTop = stackTop(&stack); if (pTop->pright == NULL || pTop->pright == plast) { printf("%c ", pTop->data); stackPop(&stack); plast = pTop; continue; } //遍历top的右子树,成为子问题 pCur = pTop->pright; } }
