目录
代码
void BST_postOrderNR(BST *bst) {
ArrayStack *as = create_array_stack(10);
lrNode *node = bst->root;
lrNode *pre = NULL;
while (!arrayStack_isEmpty(as) || node != NULL) {
while (node != NULL) {
push(as, node);
node = node->left;
}
lrNode *sNode = peek(as);
if (sNode->right == NULL || pre == sNode->right) {
pop(as);
pre = sNode;
printf("%d ", sNode->e);
}
else {
node = sNode->right;
}
}
printf("\n");
release_array_stack(as);
}
图解解释
反思
//二分搜索树的非递归后序遍历
void BST_postOrderNR(BST *bst) {
ArrayStack *as = create_array_stack(10);
lrNode *node = bst->root;
lrNode *pre = NULL;
while (!arrayStack_isEmpty(as) || node != NULL) {
while (node != NULL) {
push(as, node);
node = node->left;
}
lrNode *sNode = peek(as);//用于输出或用于指定下一个入栈元素
if (sNode->right == NULL || pre == sNode->right) {
pop(as);
pre = sNode;
printf("%d ", sNode->e);
//node = peek(as);有这一句会让父母节点不停地进入输入环节
//node = peek(as)->right;有这一句会让父母节点右孩子不停地进入输出环节
}
else {
node = sNode->right;
}
}
printf("\n");
release_array_stack(as);
}
为什么可以在不符合输出条件时指定下一个入栈元素,而不能在符合输出条件里指定下一个入栈元素?
因为需要指定下一个入栈元素的情况是要输出右节点的时候。只有父母节点的右节点没输出时才需要指定下一个入栈元素。而叶子节点和右节点已输出的父母节点都在栈中,通过lrNode *sNode = peek(as),即可得到。
如果在注释处指定入栈元素的话,永远不会输出父母节点。父母节点只能为输出右节点而被访问。右节点输出后,不停地让后面栈顶元素把自己再一次压入栈。
只有没能输出的父母节点可以指定下次入栈的元素,其他时候不需要指定。因为除了右节点,其他元素都已入栈。
一次循环只能完成 入栈和出栈 或 入栈和指定下次入栈元素 这两种模式的其中一个。每次的指定是指向右节点的。如果在注释处指定,仅适用于叶子节点输出的情况。不适用于父母节点符合输出的情况。因为父母节点符合输出时,pre == sNode->right,而为什么又要指定下次的入栈元素是自己的右节点呢?