题目
先输入一串先序遍历的字符串,根据此字符串建立一棵二叉树。
如输入先序遍历字符串ABC##DE#G##F###,#表示空格,空格字符串代表空树。建立好树后,在对二叉树中序遍历输出结果。
总结
- 树的结构体
struct TreeNode{
char data;
TreeNode* leftChild;
TreeNode* rightChild;
//表示初始化支持TreeNode(c),即data的值为c,left和right为NULL
TreeNode(char c):data(c),leftChild(NULL),rightChild(NULL){
}
};
- 树的构建过程:由于根据前序遍历的结果构建数,先new一个根节点root,然后分别利用递归构造左子树和右子树。
//根据输入的前序遍历的值构造二叉树,函数返回根节点
TreeNode* Build(int& position,string str)
{
char c=str[position];++position;
if(c=='#') return NULL;
TreeNode* root=new TreeNode(c);
root->leftChild=Build(position,str);
root->rightChild=Build(position,str);
return root;
}
- 关于二叉树的非递归中序遍历
中序遍历利用递归很好做,非递归的方式如下:
//思路:步骤一:沿着根的左孩子依次入栈,直到左孩子为空,说明已经找到可以输出的节点
//步骤二:栈顶元素出栈 。若元素没有右孩子,继续步骤二。有右孩子,右孩子入栈,转执行一。
void InOrder2(TreeNode* root)
{
stack<TreeNode*> a;
while(root!=NULL||!a.empty()){
while(root!=NULL){
a.push(root);
root=root->leftChild;
}
root=a.top();
cout<<root->data<<' ';
a.pop();
root=root->rightChild;
}
return;
}
- 关于二叉树的非递归的前序遍历
和中序遍历大致相同,代码唯一的区别是将节点的访问放在入栈之前
void InOrder2(TreeNode* root)
{
stack<TreeNode*> a;
while(root!=NULL||!a.empty()){
while(root!=NULL){
cout<<root->data<<' ';
a.push(root);
root=root->leftChild;
}
root=a.top();
a.pop();
root=root->rightChild;
}
return;
}
代码
#include <iostream>
#include <cstdio>
#include <string>
using namespace std;
struct TreeNode{
char data;
TreeNode* leftChild;
TreeNode* rightChild;
//表示初始化支持TreeNode(c),即data的值为c,left和right为NULL
TreeNode(char c):data(c),leftChild(NULL),rightChild(NULL){
}
};
//根据输入的前序遍历的值构造二叉树,函数返回根节点
TreeNode* Build(int& position,string str)
{
char c=str[position];++position;
if(c=='#') return NULL;
TreeNode* root=new TreeNode(c);
root->leftChild=Build(position,str);
root->rightChild=Build(position,str);
return root;
}
void InOrder(TreeNode* root)
{
if(root==NULL) return;
InOrder(root->leftChild);
cout<<root->data<<' ';
InOrder(root->rightChild);
return;
}
int main()
{
string str;
cin>>str;
int position=0;//记录str的下标
TreeNode* root=Build(position,str);//根据前序遍历的结果建树
InOrder(root);//中序遍历,输出结果
return 0;
}