1.结构体:
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
};
typedef struct TreeNode* Tree;
typedef struct{
Tree* array;
int top;
}Stack;
2.二叉树的前序遍历(Preorder Traversal):
LEETCODE144. 二叉树的前序遍历
//根左右
//一路[访问]到左下,为空到上一层并且直接去右节点。
void preorderTraversal(struct TreeNode* root) {
InitStack(S);
while(root||!IsEmpty(S){ //root保证刚开始栈空能进入循环。
if(root){
Visit(root);
push(S,root);
root=root->left;
}
else{
Pop(S,root);
root=root->right;
}
}
}
3.二叉树的中序遍历(Inorder Traversal):
LEETCODE94. 二叉树的中序遍历
//左根右
//一路左下,为空到上一层并且直接[访问],访问完去右节点。
void inorderTraversal(struct TreeNode* root) {
InitStack(S);
while(root||!IsEmpty(S)){
if(root){
Push(S,root);
root=root->left;
}
else{
Pop(S,root);
Visit(root);
root=root->right;
}
}
}
4.二叉树的后序遍历(Postorder Traversal):
LEETCODE145. 二叉树的后序遍历
二叉树后序遍历寻找结点路径
//左右根
//对根节点有两次访问:
//1.从左子树回来,[不能访问]节点,进入右节点。
//2.从右子树回来,[访问节点],不进入右节点,返回上一层。
//这就有了个判断问题,在根节点时看有没有访问过右节点,没访问过再进入。
//引入pre表示最近访问节点,后序遍历特点,root->right若存在必为root的最近访问节点。
//这样看自己right是不是pre就可以判定是否进入右节点。
void postorderTraversal(struct TreeNode* root) {
InitStack(S);
Tree pre=NULL;
while(root||!IsEmpty(S)){
if(root){
Push(S,root);
root=root->left;
}
else{
GetTop(S,root);
if(root->right&&root->right!=pre){
root=root->right;
else{
Pop(S,root);
Visit(root);
pre=root;
root=NULL;
}
}
}
}
4.情况分析:
对于else{}有两种情况:
1.上一层节点的左子树不存在:正常返回上层,该咋办咋办;
2.上一层节点的左子树访问完了:
1)前序和中序:此时root指向上一层节点左子树的最右下节点,为NULL,此时Pop直接到上一层后,访问该节点(左根右
为例),访问右节点;
2)后序:此时root指向上一层节点的左孩子(一路从右下上来),不为NULL,手动置NULL表示左子树访问完,保证进入
else{},Pop直接到上一层后,访问右子树(左右根);