后序遍历的非递归算法(C详细)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
后序遍历的非递归算法(C详细)
后序遍历是二叉树遍历的一种方式,它的顺序是先遍历左子树,然后
遍历右子树,最后访问根节点。
非递归实现后序遍历的算法可以使用栈来
辅助实现。
首先,我们需要定义一个树节点的数据结构,例如:
```c
struct TreeNode
int val;
struct TreeNode* left;
struct TreeNode* right;
};
```
接下来,我们使用一个辅助栈来进行非递归后序遍历。
首先需要创建
一个空栈,并将根节点入栈。
然后开始循环,直到栈为空为止。
在循环中,首先取出栈顶节点,如果该节点没有左子树且没有右子树,说明该节点是
叶子节点,可以直接输出该节点的值。
如果该节点有左子树或者右子树,
需要判断是否已经遍历过该节点的子节点。
为了实现后序遍历的顺序,我
们需要一个标记变量来记录上次访问的节点。
如果上次访问的节点是该节
点的右子树,说明该节点的左右子节点都已经访问过了,可以直接输出该
节点的值。
反之,如果上次访问的节点不是该节点的右子树,将该节点重
新入栈,并以右、左、中的顺序将其右子树、左子树入栈。
下面给出完整的代码实现:
```c
#include <stdio.h>
#include <stdlib.h>
struct TreeNode
int val;
struct TreeNode* left;
struct TreeNode* right;
};
void postOrderTraversal(struct TreeNode* root)
if (root == NULL)
return;
}
struct TreeNode* lastVisited = NULL; // 上次访问的节点struct TreeNode* node = root; // 当前遍历的节点
struct TreeNode* stack[100]; // 栈
int top = -1; // 栈顶指针
while (node != NULL , top != -1)
if (node != NULL)
stack[++top] = node; // 入栈
node = node->left; // 访问左子树
} else
struct TreeNode* temp = stack[top]; // 取出栈顶节点
if (temp->right == NULL , temp->right == lastVisited) printf("%d ", temp->val);
top--; // 出栈
lastVisited = temp; // 记录上次访问的节点
} else
node = temp->right; // 访问右子树
}
}
}
struct TreeNode* createNode(int val)
struct TreeNode* node = (struct
TreeNode*)malloc(sizeof(struct TreeNode));
if (node != NULL)
node->val = val;
node->left = NULL;
node->right = NULL;
}
return node;
int mai
//创建一个二叉树
struct TreeNode* root = createNode(1); root->left = createNode(2);
root->right = createNode(3);
root->left->left = createNode(4);
root->left->right = createNode(5); root->right->left = createNode(6); root->right->right = createNode(7);
//后序遍历二叉树
printf("后序遍历结果:"); postOrderTraversal(root);
printf("\n");
return 0;
```
以上代码中,我们使用了一个辅助数组作为栈来实现非递归遍历。
首
先定义了一个空栈,然后将根节点入栈。
在循环中,如果当前节点不为空,说明还有未遍历的左子节点,将其入栈,并继续寻找左子树。
如果当前节
点为空,说明已经遍历到了一个叶子节点,需要判断是否需要输出该节点
的值。
如果上次访问的节点是该节点的右子树,说明该节点的左右子节点
都已经访问过了,可以直接输出该节点的值。
反之,将该节点重新入栈,
并继续寻找右子树。
循环结束后,即完成了非递归后序遍历。