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;
}
};

京公网安备 11010502036488号