vector<vector<int> > Print(TreeNode* pRoot) {
vector<vector<int> > result;
stack<TreeNode *> stack1,stack2;
if(pRoot!=NULL)
stack1.push(pRoot);
TreeNode *node = NULL;
while(!stack1.empty() || !stack2.empty()){
vector<int> data;
if(!stack1.empty()){
while(!stack1.empty()){
node = stack1.top();
stack1.pop();
data.push_back(node->val);
if(node->left!=NULL)
stack2.push(node->left);
if(node->right!=NULL)
stack2.push(node->right);
}
result.push_back(data);
}
else if(!stack2.empty()){
while(!stack2.empty()){
node = stack2.top();
stack2.pop();
data.push_back(node->val);
if(node->right!=NULL)
stack1.push(node->right);
if(node->left!=NULL)
stack1.push(node->left);
}
result.push_back(data);
}
}
return result;
}
vector<vector<int> > Print(TreeNode* pRoot) {
vector<vector<int> > result;
if(pRoot == NULL)
return result;
bool flag = true;
queue<TreeNode *> q;
q.push(pRoot);
while(!q.empty())
{
int size = q.size();
vector<int> num;
while(size --)
{
TreeNode *cur = q.front();
q.pop();
num.push_back(cur->val);
if(cur->left != NULL)
{
q.push(cur->left);
}
if(cur->right != NULL)
{
q.push(cur->right);
}
}
if(!flag)
{
reverse(num.begin(), num.end());
}
result.push_back(num);
flag = !flag;
}
return result;
}
2..把二叉树打印成多行
题目:从上到下打印二叉树,同一层的结点按从左到右的顺序打印,每一层打印一行。
分析:与层序遍历二叉树相似。
实现代码:
vector<vector<int> > Print(TreeNode* pRoot)
{
vector<vector<int> > vec;
if(pRoot == NULL)
return vec;
queue<TreeNode*> q;
q.push(pRoot);
while(!q.empty())
{
int lo = 0;
int hi = q.size();
vector<int> c;
while(lo++ < hi)
{
TreeNode *t = q.front();
q.pop();
c.push_back(t->val);
if(t->left)
{
q.push(t->left);
}
if(t->right)
{
q.push(t->right);
}
}
vec.push_back(c);
}
return vec;
}
3.序列化二叉树
分析:按照先序遍历二叉树的顺序,先遍历根节点,再左结点,后右节点,当到“#”时,说明左结点或者右节点为NULL,同样反序列化也是一样的。
实现代码:
char* Serialize(TreeNode *root) {
if(root==NULL)
return NULL;
string str;
Serialize1(root,str);
return const_cast<char*>(str.c_str());
}
TreeNode* Deserialize(char *str) {
if(str==NULL||*str=='\0')
return NULL;
int num=0;
return Deserialize1(str,num);
}
void Serialize1(TreeNode *root,string &str)
{
if(root==NULL)
{
str+="#,";
return ;
}
char ch[10];
sprintf(ch,"%d",root->val);
str+=ch;
str+=",";
Serialize1(root->left,str);
Serialize1(root->right,str);
}
TreeNode* Deserialize1(char *str,int &num)
{
int val=0;
if(str[num]=='#')
{
num+=2;
return NULL;
}
while(str[num]!=','&&str[num]!='\0')
{
val=val*10+str[num]-'0';
num++;
}
num++;
TreeNode *root=new TreeNode(val);
root->left=Deserialize1(str,num);
root->right=Deserialize1(str,num);
return root;
}
4.二叉搜索树的第K个结点
题目:给定一棵二叉搜索树,请找出其中第K大的结点。
分析:中序遍历一颗二叉搜索树,遍历的序列是递增的,因此只要中序遍历后,就可以找到它的第K大结点。
实现代码:
TreeNode* KthNode(TreeNode* pRoot, unsigned int& k)
{
if(pRoot == NULL || k == 0)
{
return NULL;
}
TreeNode* ret = NULL;
if(pRoot->left != NULL)
{
ret = KthNode(pRoot->left, k);
}
if(ret == NULL)
{
if(k == 1)
{
ret = pRoot;
}
else
{
k--;
}
}
if(ret == NULL && pRoot->right != NULL)
{
ret = KthNode(pRoot->right, k);
}
return ret;
}
5.求树中两个结点的最低公共祖先
1). 如果是二叉搜索树,因为二叉搜索树的左子树的结点都比父结点小,右子树的结点都比父结点大,因此只需要从树的根结点开始与两个输入的结点比较,如果当前结点的值比它们都大,则最低的公共父结点在当前结点的左子树中,接着遍历当前结点的左子结点。如果当前结点的值比它们都小,则最低的公共父结点在当前结点的右子树中,接着遍历当前结点的右子结点。直到找到第一个在两个输入结点的值之间的结点,则这个结点就是最低的公共祖先。
2).如果只是一颗普通的树且有指向父结点的指针,则这个问题就转化成了求两个链表的第一个公共结点。
3).如果只是一颗普通的树且没有指向父结点的指针
方法一(需要对同一个节点遍历多次):可以从根节点遍历这棵树,每遍历到一个结点时 ,就判断两个输入结点是不是在它的子树中,如果在,则分别遍历它的所有子结点 ,并判断输入结点是否在它们的子树中,直到找到一个结点自己包含输入结点而它的的子结点中没有,则该结点就是最低的公共祖先。
方法二(借助辅助空间):用两个链表分别保存从根节点到输入结点的路径,然后就问题就转化成了求两个链表的最后公共结点。