user-0 提问: 学C到现在，出了个群里没人解决的问题，来论坛里找前辈。

回复:
user: user-1
content: 看着那些宏定义，有种想查找替换的感觉。。。

user: user-2
content: 这个代码真的是正确的么，          if (p->leftChild)         {             Push(&S, p->rightChild);         }         if (p->rightChild)         {             Push(&S, p->leftChild);         }  我觉得应该改为          if (p->rightChild)         {             Push(&S, p->rightChild);         }         if (p->leftChild)         {             Push(&S, p->leftChild);         }  这里的判断只是用来确认要压栈的指针非空而已吧

user: user-3
content: /* 示例： a b c d  e 单支左子树a-b-d-e 和右子树a-c，显然不平衡哈 下面是你核心代码： */ Push(&S, T);//树根a压栈     while (!StackEmpty(S))//栈非空     {         Pop(&S, &p);//弹出a         if (!Visit(p->data))//访问a         {             return ERROR;         }         if (p->leftChild)         {             Push(&S, p->rightChild);//b压栈         }         if (p->rightChild)         {             Push(&S, p->leftChild);//c压栈         }     }  //第2次循环体执行      while (!StackEmpty(S))//栈：bc非空     {         Pop(&S, &p);//弹出c         if (!Visit(p->data))//访问c         {             return ERROR;         }         if (p->leftChild)//c无左右孩子，下面不执行         {             Push(&S, p->rightChild);         }         if (p->rightChild)         {             Push(&S, p->leftChild);         }     }  //第3次循环体执行      while (!StackEmpty(S))//栈：b；非空     {         Pop(&S, &p);//弹出b         if (!Visit(p->data))//访问b         {             return ERROR;         }         if (p->leftChild)         {             Push(&S, p->rightChild);//d压栈         }         if (p->rightChild)//无R孩子         {             Push(&S, p->leftChild);         }     }  //第4次循环体执行      while (!StackEmpty(S))//栈：d；非空     {         Pop(&S, &p);//弹出d         if (!Visit(p->data))//访问d         {             return ERROR;         }         if (p->leftChild)         {             Push(&S, p->rightChild);//e压栈         }         if (p->rightChild)//d无R孩子         {             Push(&S, p->leftChild);         }     }  //第5次循环体执行      while (!StackEmpty(S))//栈：e；非空     {         Pop(&S, &p);//弹出e         if (!Visit(p->data))//访问e         {             return ERROR;         }  //e无左右孩子，下面不执行         if (p->leftChild)         {             Push(&S, p->rightChild);         }         if (p->rightChild)         {             Push(&S, p->leftChild);         }     }  //第6此检测循环条件，栈空，退出循环。over //这里无非是“根，右孩子，左孩子”先顺序访问的。有点不常用，常用的是“根，左孩子，右孩子”不过没有差别 //中间if语句调整以下就变换过来了  你滴明白？

user: user-4
content: http://www.codeproject.com/Articles/418776/How-to-replace-recursive-functions-using-stack-and

user: user-5
content: 自己试着用非递归实现二叉树的遍历你就能想通了

user: user-6
content: 二叉树的非递归算法,是对递归算法的模拟  二叉树遍历中,前序遍历的非递归算法做法是  1)处理当前(根)节点, 最先处理根节点,所以是前序遍历 2)然后处理左右子树         2.1)有左右子树,右子入栈.            接着左子成为新的当前(根)节点,        2.2)无左子,右子成为新的当前(根)结点        2.3)每当处理到无左右子的时候.              弹出压栈的节点,----某子树的右节点 .....逐级处理.直到栈空.  因为左子直接处理,所以不用压栈. 无左子且无右子,则为叶子节点,不用继续遍历了. 于是处理栈中存放的数据----被压入栈中的某个右子树.  不论是否平衡二叉树,都可以完成遍历

user: user-0
content: 引用 6 楼 zhao4zhong1 的回复:《算法精解（C语言实现）》 《算法精解C语言实现》例子代码\examples_pc\include\bitree.h 《算法精解C语言实现》例子代码\examples_pc\examples\bistree\ex-1.c 前辈不好意思，我水平菜，实在消化不了您说的这些高深的。 就我问的那些您给解答一下呗。

user: user-4
content: 《算法精解（C语言实现）》 《算法精解C语言实现》例子代码\examples_pc\include\bitree.h 《算法精解C语言实现》例子代码\examples_pc\examples\bistree\ex-1.c

user: user-4
content: 提示你在调试类似树、图这类复杂数据结构的代码时，随时显示其可视化的内容。  “给定一个小点的输入，完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门！ 递归函数关注以下几个因素 ·退出条件 ·参数有哪些 ·返回值是什么 ·局部变量有哪些 ·全局变量有哪些 ·何时输出 ·会不会导致堆栈溢出

user: user-0
content: 引用 2 楼 zhao4zhong1 的回复:仅供参考#include <stdio.h> #include <stdlib.h> #include <string.h>  struct node {     char *word;     struct node *left, *right; };  struct node *tree;  void showTree(struct node *aTree) {     if (aTree == NULL) return;     printf(" @%p: %s \t/%p\t\t\\%p\n", aTree, aTree->word, aTree->left, aTree->right);     showTree(aTree->left);     showTree(aTree->right); }  这是咋回事？不明白你的意思

user: user-0
content: 等人来解答。

user: user-4
content: 仅供参考#include <stdio.h> #include <stdlib.h> #include <string.h>  struct node {     char *word;     struct node *left, *right; };  struct node *tree;  void showTree(struct node *aTree) {     if (aTree == NULL) return;     printf(" @%p: %s \t/%p\t\t\\%p\n", aTree, aTree->word, aTree->left, aTree->right);     showTree(aTree->left);     showTree(aTree->right); }  struct node *nodeWith(char *aWord) {     struct node *node;     node = (struct node *)calloc(1,sizeof(struct node));     node->word = aWord;     return (node); }  // Pretty much as Rubin started it on the board and others refined struct node *findOrInsert(struct node *aTree, char *aWord) {     int cmp;     printf("findOrInsert(...%s\n", aWord);     if ((cmp = strcmp(aWord, aTree->word)) == 0) return(aTree);     if (cmp < 0) {         if (aTree->left) return (findOrInsert(aTree->left, aWord));         aTree->left = nodeWith(aWord);         return (aTree->left);     } else {         if (aTree->right) return (findOrInsert(aTree->right, aWord));         aTree->right = nodeWith(aWord);         return (aTree->right);     } }  int main() {     tree = (struct node *)calloc(1,sizeof(struct node));     tree->word = "root";     showTree(tree);     findOrInsert(tree, "leave");     showTree(tree);     findOrInsert(tree, "house");     showTree(tree);     findOrInsert(tree, "mouse");     showTree(tree);     findOrInsert(tree, "house");     showTree(tree);     return 0; } // @00411900: root        /00000000               \00000000 //findOrInsert(...leave // @00411900: root        /00411870               \00000000 // @00411870: leave       /00000000               \00000000 //findOrInsert(...house //findOrInsert(...house // @00411900: root        /00411870               \00000000 // @00411870: leave       /00411830               \00000000 // @00411830: house       /00000000               \00000000 //findOrInsert(...mouse //findOrInsert(...mouse // @00411900: root        /00411870               \00000000 // @00411870: leave       /00411830               \004117F0 // @00411830: house       /00000000               \00000000 // @004117F0: mouse       /00000000               \00000000 //findOrInsert(...house //findOrInsert(...house //findOrInsert(...house // @00411900: root        /00411870               \00000000 // @00411870: leave       /00411830               \004117F0 // @00411830: house       /00000000               \00000000 // @004117F0: mouse       /00000000               \00000000 //

user: user-0
content: 也就是因为无右子树，左子树也没法进栈了。  还有个问题，是关于栈操作的。 Status GetTop(SqStack S,SElemType *e){     if(S.top == S.base)     {         return FALSE;     }     else     {         *e = *(S.top-1);         return OK;     } 以及 Status Pop(SqStack *S,SElemType *e){     if(S->top==S->base)     {         return ERROR;     }     *e = *(--S->top);     return OK; } 请帮忙解释下*e = *(S.top-1);和  *e = *(--S->top);各是什么意思。因为中序非递归遍历其实我也有点看不明白。 顺便（算法博大精深，层序遍历已经看的我醉了。）