先序遍历
递归方法:
这个方法简单,只要按照 自己-> 右儿子 -> 左儿子的顺序就可以了
非递归法,开始时根结点在栈中,然后
{
栈顶输弹出
如果有右儿子,右儿子入栈
如果有左儿子,左儿子入栈
}
这样循环,直到栈为空。栈顶一直是下一个要打印的根结点。
#if METHOD == 1
/*
这里对vector的使用方法要得当,把两个vector拼在一起的方法是
把out1,out2,拼成(out1,out2)
out2.insert(out2.begin(),out1.begin(),out1.end());//out1,out2顺序不要弄错
*/
class Solution {
public:
vector<int> preorderTraversal(TreeNode *root) {//中左右
vector<int> out;
if(root == NULL)
return out;
vector<int> out1 = preorderTraversal(root->left);
vector<int> out2 = preorderTraversal(root->right);
out.insert(out.begin(),out2.begin(),out2.end()); //右
out.insert(out.begin(),out1.begin(),out1.end()); //左
out.insert(out.begin(),root->val); //中
return out;
}
};
#elif METHOD == 2
//堆栈方法
//这个方法不太好理解,需要加以研究
class Solution {
public:
vector<int> preorderTraversal(TreeNode *root) {
vector<int> out;
if(root == NULL)
return out;
//TreeNode *head = root; //就是记录上一个弹出的结点
treenodeStack.push(root);
while(!treenodeStack.empty())
{
TreeNode *cur = treenodeStack.top();//增加一个记录点
treenodeStack.pop();
out.push_back(cur->val);
if(cur->right != NULL) treenodeStack.push(cur->right)/*,printf("lpush = %d\n",cur->right->val)*/;
if(cur->left != NULL) treenodeStack.push(cur->left)/*,printf("rpush = %d\n",cur->left->val)*/;
}
return out;
}
private:
stack<TreeNode*> treenodeStack;
};
#endif
中序遍历
中序遍历二叉树:
递归法,不多说,左孩子-》自己-》右孩子这样递归就可以了。
循环法:使用栈,下面的代码还是比较好的。
其中指针p的使用非常关键
#if 0
class Solution {
public://中序遍历,左中右
vector<int> inorderTraversal(TreeNode *root) {
vector<int> out;
if(root == NULL) return out;
vector<int> outleft = inorderTraversal(root->left);
vector<int> outright = inorderTraversal(root->right);
out.insert(out.begin(),outright.begin(),outright.end());
out.insert(out.begin(),root->val);
out.insert(out.begin(),outleft.begin(),outleft.end());
return out;
}
};
#elif 1//栈 ------------赞!!!!
class Solution {
public://中序遍历,左中右
vector<int> inorderTraversal(TreeNode *root) {
vector<int> out;
stack<TreeNode *> stk;
TreeNode *p = root;
while(!stk.empty() || p)
{
if(p != NULL)
{
stk.push(p);
p = p->left;
}
else
{
p = stk.top();
stk.pop();
out.push_back(p->val);
p = p->right;
}
}
return out;
}
};
#endif
后序遍历
递归方法:
这个方法简单,只要按照左儿子 -> 右儿子 -> 自己的顺序就可以了
非递归方法1:
相比于前序遍历,后续遍历思维上难度要大些,前序遍历是通过一个stack,首先压入父亲结点,然后弹出父亲结点,并输出它的value,之后压人其右儿子,左儿子即可。然而后序遍历结点的访问顺序是:左儿子 -> 右儿子 -> 自己。那么一个结点需要两种情况下才能够输出:第一,它已经是叶子结点;第二,它不是叶子结点,但是它的儿子已经输出过(代码里非递归方法head就是用来记录访问过的儿子的)。那么基于此我们只需要记录一下当前输出的结点即可。对于一个新的结点,如果它不是叶子结点,儿子也没有访问,那么就需要将它的右儿子,左儿子压入。如果它满足输出条件,则输出它,并记录下当前输出结点。输出在stack为空时结束。
非递归方法2:
利用堆栈很按后序的逆序输入再做一次逆序
从一开始,就按 自己->右儿子->左儿子顺序输出,最后做一下逆序就好
#if METHOD == 1
/*
这里对vector的使用方法要得当,把两个vector拼在一起的方法是
把out1,out2,拼成(out1,out2)
out2.insert(out2.begin(),out1.begin(),out1.end());//out1,out2顺序不要弄错
*/
class Solution {
public:
vector<int> postorderTraversal(TreeNode *root) {
vector<int> out;
if(root == NULL)
return out;
vector<int> out1 = postorderTraversal(root->left);
vector<int> out2 = postorderTraversal(root->right);
out.insert(out.begin(),root->val); //中
out.insert(out.begin(),out2.begin(),out2.end()); //右
out.insert(out.begin(),out1.begin(),out1.end()); //左
return out;
}
};
#elif METHOD == 2
//堆栈方法
//这个方法不太好理解,需要加以研究
class Solution {
public:
vector<int> postorderTraversal(TreeNode *root) {
vector<int> out;
if(root == NULL)
return out;
TreeNode *head = root; //就是记录上一个弹出的结点
treenodeStack.push(root);
while(!treenodeStack.empty())
{
TreeNode *cur = treenodeStack.top();//增加一个记录点
if(cur->left == head || cur->right== head ||(cur->left == NULL && cur->right == NULL))//这个条件很关键
{
treenodeStack.pop();
out.push_back(cur->val);
head = cur;
//printf("pop = %d\n",cur->val);
//system("pause");
}
else
{
if(cur->right != NULL) treenodeStack.push(cur->right)/*,printf("lpush = %d\n",cur->right->val)*/;
if(cur->left != NULL) treenodeStack.push(cur->left)/*,printf("rpush = %d\n",cur->left->val)*/;
}
}
return out;
}
private:
stack<TreeNode*> treenodeStack;
};
#elif METHOD == 3
/*
这个方法赞呀!自己->右儿子->左儿子顺序输出,最后做一下逆序就好
*/
class Solution {
public:
vector<int> postorderTraversal(TreeNode *root) {
vector<int> res;
if(root == NULL)
return res;
vector<TreeNode*> stc;
stc.push_back(root);
while(!stc.empty()) {
TreeNode* node = stc.back();
res.push_back(node->val);
stc.pop_back();
if(node->left != NULL) {
stc.push_back(node->left);
}
if(node->right != NULL) {
stc.push_back(node->right);
}
}
reverse(res.begin(), res.end());
return res;
}
};
#endif