1.从上到下打印二叉树
思路:利用队列,每次打印一个节点的时候,如果该节点有子节点,就把该节点的子节点放到一个队列的末尾。然后到队列的头部取出最早进入队列的节点,重复前面的打印操作,知道队列中所有的节点都被打印出来。

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};*/
class Solution {
public:
    vector<int> PrintFromTopToBottom(TreeNode* root) {
        vector<int> res;
        queue<TreeNode*> node;
        if(root==nullptr) return res;
        node.push(root);
        while(node.size()!=0)
        {
            res.push_back(node.front()->val);
            TreeNode* p=node.front();
            node.pop();
            //按层遍历二叉树
            if(p->left)
                node.push(p->left);
            if(p->right)
                node.push(p->right);   
        }
        return res;
    }
};

问2:如果要按层换行打印呢?
思路:利用两个变量,一个变量a记录当前层中还未打印的节点数,另一个b记录下一层节点的数目。当打印一个数时,判断有无叶子节点,有b加一,将此节点从队列弹出,a--,如果a等于0,表示此层被打完,令a=b,b=0。

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};*/
class Solution {
public:
    void Print(TreeNode *root)
    {
        if(root==nullptr) return;
        queue<TreeNode*> q;
        q.push(root);
        int cur=1;
        int next=0;//两个重要变量
        while(q.size()!=0)
        {
            printf("%d",q.front()->val);
            TreeNode *p=q.front();
            q.pop();
            if(p->left)
            {
                q.push(p->left);
                next++;//下一层数目加一
            }
            if(p->right)
            {
                q.push(p->right);
                next++;//下一层数目加一                
            }
            cur--;
            if(cur==0)
            {
                printf("\n");
                cur=next;
                next=0;//打印完一行换下一行
            }
        }
    }
};

问3:如果要求之字形打印呢?
思路:利用两个栈,当打印某一层的节点时,把下一层的节点保存到相应的栈里。如果打印的是奇数层,则先左再右把子节点保存在第一个栈里,如果打印的是偶数层,则先右再左把子节点保存在第二个栈里。

/*
/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
public:
    vector<vector<int> > Print(TreeNode* pRoot) {
        vector<vector<int> > res;
        vector<int> v;
        if(pRoot==nullptr) return res;
        stack<TreeNode*> s[2];
        int cur=0;
        int next=1;
        s[cur].push(pRoot);
        while(!s[0].empty()||!s[1].empty())
        {
            TreeNode* p=s[cur].top();
            v.push_back(s[cur].top()->val);
            s[cur].pop();
            if(cur==0)
            {
                if(p->left)
                    s[next].push(p->left);
                if(p->right)
                    s[next].push(p->right);
            }
            else
            {
                if(p->right)
                    s[next].push(p->right);
                if(p->left)
                    s[next].push(p->left);
            }
            if(s[cur].empty())
            {
                res.push_back(v);
                v.clear();
                cur=1-cur;
                next=1-next;
            }
        }
        return res;
    }   
};

2.二叉搜索树的后序遍历序列
思路:二叉搜索树后序遍历的特点,最后一个点是根节点,前面第一部分是左子树节点的值,都小于根节点;第二部分是右子树节点的值,都比根节点的值大。我们可以采取递归的思路,首先找到左子树,然后找右子树,然后分别递归遍历左右子树是否符合条件。

class Solution {
public:
    bool VerifySquenceOfBST(vector<int> sequence) {
      /*BST的后序序列的合法序列是,对于一个序列S,最后一个元素是x (也就是根),如果去掉最后一个
      元素的序列为T,那么T满足:T可以分成两段,前一段(左子树)小于x,后一段(右子树)大于x,且
      这两段(子树)都是合法的后序序列*/
        //利用递归
        int i=0;
        int len=sequence.size();
        vector<int> left,right;
        if(len<=0) return false;
        int root=sequence[len-1];//根节点是数组最后一个元素
        for(;i<len-1;i++)
        {
            if(sequence[i]>root) break;//从头开始遍历,若大于根节点,左子树结束
            left.push_back(sequence[i]);
        }
        int j=i;
        for(;j<len-1;j++)
        {
            if(sequence[j]<root) return false;//遍历右子树,若小于根节点,返回false
            right.push_back(sequence[j]);
        }
        bool flag1=true;
        if(i>0)//有左子树再递归遍历左子树
        flag1=VerifySquenceOfBST(left);
        bool flag2=true;
        if(i<len-1)//有右子树再递归遍历右子树
        flag2=VerifySquenceOfBST(right);
        if(flag1&&flag2)
            return true;
        else
            return false;
    }
};

3.二叉树中和为某一值的路径
思路:利用前序遍历,访问一个节点,就将该节点添加在路径上,并且累加该节点的值。如果该节点为叶子节点,并且路径中节点值的和刚好符合条件,就打印一条路径。当节点访问结束后(到叶子节点),递归函数将自动回到它的父节点。但在推出函数前要在路径上删除当前节点并减去当前节点的值,以确保返回父节点时的路径刚好是从根节点到父节点。这里为了打印时得到路径所有的点,用vector代替了STL中的stack。

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};*/
class Solution {   
public:
    vector<vector<int>> result;
    vector<int> buf;
    vector<vector<int> > FindPath(TreeNode* root,int expectNumber) {
        //利用递归
        if(root==NULL) return result;
        buf.push_back(root->val);
        if((expectNumber-root->val)==0&&root->left==NULL&&root->right==NULL)
        {
            result.push_back(buf);
        }
        FindPath(root->left,expectNumber-root->val);
        FindPath(root->right,expectNumber-root->val);
        if(buf.size()!=0)
            buf.pop_back();
        return result;
    }
};