从图上来看如果我们想遍历一个二叉树,每个节点都要经历进来,中间,出去这三次
递归写法
前序遍历(进来)
- A-B-D-C-E-F
递归思想(根->左->右) - A根->B左–>C右
- B->D左->NULL右
- D->NULL左->NULL右
- C->E左->F右
- E->NULL->NULL
- F->NULL->NULL
void _preorderTraversal(struct TreeNode*root,int**arry,int* size){
if(root==NULL){
return;
}
*((*arry)+(*size)++) = root->val;
_preorderTraversal(root->left,arry,size);
_preorderTraversal(root->right,arry,size);
}
int* preorderTraversal(struct TreeNode* root, int* returnSize) {
int* arry = (int *)malloc(sizeof(int)*100*10000);
int size = 0;
_preorderTraversal(root,&arry,&size);
*returnSize = size;
return arry;
}
中序遍历(中间)
- D-B-A-E-C-F
递归思想(左->根->右) - D->B->NULL
- B->A->NULL
- A->=->C
- E->C->F
- C->=->F
- F->=->NULL
void _inorderTraversal(struct TreeNode*root,int**arry,int* size){
if(root==NULL){
return;
}
_inorderTraversal(root->left,arry,size);
*((*arry)+(*size)++) = root->val;
_inorderTraversal(root->right,arry,size);
}
int* inorderTraversal(struct TreeNode* root, int* returnSize) {
int* arry = (int *)malloc(sizeof(int)*100*10000);
int size = 0;
_inorderTraversal(root,&arry,&size);
*returnSize = size;
return arry;
}
后序遍历(出去)
- D-B-E-F-C-A
递归思想(左->右->根) - D->NULL->B
- B->C->A
- E->F->C
- NULL->F->C
- =->C->A
- A
void _postorderTraversal(struct TreeNode*root,int**arry,int* size){
if(root==NULL){
return;
}
_postorderTraversal(root->left,arry,size);
_postorderTraversal(root->right,arry,size);
*((*arry)+(*size)++) = root->val;
}
int* postorderTraversal(struct TreeNode* root, int* returnSize) {
int* arry = (int *)malloc(sizeof(int)*100*10000);
int size = 0;
_postorderTraversal(root,&arry,&size);
*returnSize = size;
return arry;
}
二叉树前序|中序|后序非递归写法(自行用栈实现)
void PreorderTraversalNor(TreeNode*root){//前序
TreeNode *cur = root;
TreeNode*top;
TreeNode*last = NULL
std::stack<TreeNode*> st;
while(!st.empty()||cur!=NULL){
while (cur!=NULL){
//第一次访问节点:cur;
printf("%c",cur->val)//前序
st.push(cur);
cur = cur->left;
}
top = st.top();//从栈顶取元素
if(top->right!=NULL&&top->right!=last){
cur = top->right;//第二次访问节点:top;如果其右子节点被pop则说明到了第三次;
printf("%c",cur->val)//中序,注意在右边无子树二三一起进行,所以单独打印一次
}
if(top->right==NULL){
printf("%c",cur->val)//中序
}
else{
printf("%c",cur->val)//后序
st.pop();//第三次访问节点:top;
last= top;
}
}
}
注意:前序与后序:无法分辨左右子树,方便找根;中序:方便区分左右子树;没法找根