对于二叉树来说,只要按照下面的模板可以很容易地实现先序、中序和后序的递归遍历二叉树。
void visit(TreeNode *node) { //operation 1 if (node->leftChild != nullptr) visit(node->leftChild); //operation 2 if (node->rightChild != nullptr) visit(node->rightChild); //operation 3 }
使用递归可以使代码变得简洁,明了。我们不用考虑计算机底层的递归工作栈是怎么实现的,只要写好递归式,给出递归终止条件,就可以把剩余的计算工作交给计算机去执行。所以说递归是个好东东啊。但是追求真相的人,往往不会满足于此的,一定弄明白背后的工作原理。
哈哈这就是古人云:"不可去名上理会。须求其所以然。"
OK,下面我把今晚写的遍历二叉树的非递归算法分享一下。
TreeNode *assistStack[MAXSIZE];//辅助栈模拟系统的递归工作栈 bool visited[MAXSIZE] = { false };//设置访问标志位 void visit(char value) { printf("%c ", value); }
先序遍历非递归实现
void preOrderOfNonRecurrence(TreeNode *root) { int top = -1; TreeNode *rNode = root; visit(rNode->value); assistStack[++top] = rNode; //将左子树全部入栈,边入栈便访问 while (rNode->leftChild != nullptr) { rNode = rNode->leftChild; printf("%c ", rNode->value); assistStack[++top] = rNode; } //将栈中的左子树结点依次出栈,则先进去的结点最后出来。 //这样对每个出栈的结点,判断其是否有右子树。如果有则将每个右子树结点的左子树入栈。 //记住只有入栈时才访问结点。 while (top != -1) { if (assistStack[top]->rightChild != nullptr) { rNode = assistStack[top]->rightChild; top--; printf("%c ", rNode->value); while (rNode->leftChild != nullptr) { rNode = rNode->leftChild; printf("%c ", rNode->value); assistStack[++top] = rNode; } } else { top--; } } }
中序遍历非递归实现
void inOrderOfNonRecurrence(TreeNode *root) { TreeNode *rNode = root; int top = -1; assistStack[++top] = rNode; while (rNode->leftChild != nullptr) { rNode = rNode->leftChild; assistStack[++top] = rNode; } while (top != -1) { rNode = assistStack[top--]; visit(rNode->value); if (rNode->rightChild != nullptr) { rNode = rNode->rightChild; assistStack[++top] = rNode; while (rNode->leftChild != nullptr) { rNode = rNode->leftChild; assistStack[++top] = rNode; } } } }
后序遍历非递归实现
void postOrderOfRecurrence(TreeNode *root) { TreeNode* rNode = root; int top = -1; assistStack[++top] = rNode; visited[top] = false; while (rNode->leftChild != nullptr) { rNode = rNode->leftChild; assistStack[++top] = rNode; visited[top] = false; } while (top != -1) { rNode = assistStack[top]; visited[top] = true; if (rNode->rightChild != nullptr) { rNode = rNode->rightChild; assistStack[++top] = rNode; visited[top] = false; while (rNode->leftChild != nullptr) { rNode = rNode->leftChild; assistStack[++top] = rNode; visited[top] = false; } } while (visited[top] == true && top != -1) { visit(assistStack[top]->value); top--; } } }
上面代码只对先序遍历的非递归实现做了注释,其它两种没有进行注释,可以对比理解一下!
2016年3月30日补充:
先序遍历二叉树非递归方法:
void PreOrderOfNoRecu(BinaryTreeNode *root) { if (root == NULL) return; BinaryTreeNode *stack[100]; int top = -1; for (int i = 0; i < 100; i++) stack[i] = NULL; BinaryTreeNode *p = root; BinaryTreeNode *q = NULL; stack[++top] = p; while (top != -1) { while (p) { visit(p->value); p = p->lchild; if (p == NULL) break; stack[++top] = p; } q = stack[top--]; p = q->rchild; if (p != NULL) stack[++top] = p; } }
中序遍历二叉树非递归方法:
void InOrderOfNoRecurrence(BinaryTreeNode *root) { if (root == NULL) return; BinaryTreeNode *stack[100]; for (int i = 0; i < 100; i++) stack[i] = NULL; int top = -1; BinaryTreeNode *node = root; BinaryTreeNode *p = NULL, *q = NULL; while (node != NULL) { stack[++top] = node; node = node->lchild; } while (top != -1) { q = stack[top--]; visit(q->value); p = q->rchild; while (p) { stack[++top] = p; p = p->lchild; } } }
后序遍历二叉树非递归方法:
void PostOrderOfNoRecurrence(BinaryTreeNode *root) { if (root == NULL) return; BinaryTreeNode *stack[100]; bool visited[100]; for (int i = 0; i < 100; i++) { stack[i] = NULL; visited[i] = false; } int top = -1; BinaryTreeNode *p, *q; BinaryTreeNode *node = root; while (node) { stack[++top] = node; node = node->lchild; } while (top != -1) { q = stack[top]; visited[top] = true; p = q->rchild; while (p) { stack[++top] = p; p = p->lchild; } while (visited[top] && top != -1) { q = stack[top]; visit(q->value); visited[top] = false; top--; } } }