树的数据结构如下:
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
};
一、先序遍历
按照“根结点-左孩子-右孩子”的顺序进行访问
1、递归实现
//先序遍历,根-左-右
void preorder(TreeNode *root){
//递归写法
if(root!=NULL){
cout<<root->val<<"";
preorder(root->left);
preorder(root->right);
}
}
2、非递归实现
设置一个栈s,首先判断根节点是否为空,如为空直接返回,不为空就将根节点入栈,然后执行如下循环。
判断当前栈是否非空,非空时,取出栈顶节点node,遍历node的值。然后判断node的右孩子是否存在,若存在将右孩子入栈。最后判断node的左孩子是否存在,若存在将左孩子入栈。然后继续循环判断栈是否非空....
代码如下:
vector<int>preorder(TreeNode *root){
vector<int> res;
if(NULL == root){
return res;
}
stack<TreeNode*> s;
s.push(root);
while(!s.empty()){
TreeNode* cur = s.top();
s.pop();
res.push_back(cur->val);
if(cur->right){
s.push(cur->right);
}
if(cur->left){
s.push(cur->left);
}
//因为栈是先进后出,因此应先将右孩子结点入栈,然后再将左孩子入栈
}//while
return res;
}
二、中序遍历
按照“左孩子-根结点-右孩子”的顺序进行访问
1、递归实现
void inorder(TreeNode *root){
if(root != NULL){
inorder(root->left);
cout<<root->val<<""<<endl;
inorder(root->right);
}
}
2、非递归实现
vector<int>inorder(TreeNode *root){
vector<int> res;
if(NULL == root){
return res;
}
stack<TreeNode*> s;
TreeNode *cur = root;
while(cur != NULL || !s.empty()){
while(cur != NULL){
s.push(cur);
cur = cur->left;
}
if(!s.empty()){
cur = s.top();
res.push_back(cur->val);
s.pop();
cur = cur->right;
}
}//while
return res;
}
三、后序遍历
按照“左孩子-右孩子-根结点”的顺序进行访问
1、递归实现
void postorder(TreeNode *root){
if(root != NULL){
postorder(root->left);
postorder(root->right);
cout<<root->val<<""<<endl;
}
}
2、非递归实现
借用先序遍历的非递归实现思路,后序遍历是“左-右-根”,即“根-右-左”的逆序,先用先序遍历思路实现“根-右-左”,然后将vector逆序一下即可。
vector<int>postorder(TreeNode *root){
//先实现根-右-左
vector<int> res;
if(NULL == root){
return res;
}
stack<TreeNode*> s;
s.push(root);
while(!s.empty()){
TreeNode * node = s.top();
s.pop();
res.push_back(node->val);
if(node->left){
s.push(node->left);
}
if(node->right){
s.push(node->right);
}
}//while
reverse(res.begin(), res.end());
return res;
}