二叉树遍历
1、题目和要求
时间限制:1s,内存限制:32MB,特殊判题:否
2、总结
这次用指针用的很多,调试程序时,因为对概念的不清楚,耽误了好久。
1)定义类时,数据成员不能被指定为自身类型,但可以是指向自身类型的指针或引用。因为如果类包含自身类的对象,存在无限初始化的问题,编译器无法计算所需空间。具体解释参见:为什么C++类定义中,数据成员不能被指定为自身类型,但可以是指向自身类型的指针或引用?为什么在类体内可以定义将静态成员声明为其所属类的类型呢 ?
2)lchild、rchild
必须初始化为NULL
,它本身是有值的,并且不是NULL
。
3)必须在主函数或全局变量中,采用静态数组或动态申请内存空间的方式,为所有节点申请内存空间!!!不能在函数中定义一个Node
类型后,赋值给lchild、rchild
,函数执行结束,Node
就被释放了。
4)树的遍历函数第一次写由于没有写if(node->lchild != NULL)
,从而陷入了死循环。
5)Node construct(string preOrder, string inOrder)
函数有 3 种返回值:返回Node
,返回Node *
,没有返回值。这篇用到了后两种返回方式:2.4 排序二叉树(包括中序遍历在内的两种遍历结果可以唯一确定一棵二叉树)。
除了直接在参数中传string
,还可以采用construct(int s1, int e1, int s2, int e2)
,其中前序遍历结果为由preOrder[s1]
到preOrder[e1]
,中序遍历结果为inOrder[s2]
到inOrder[e2]
。这样的好处是,分割字符串时代码行数大大减少,使用construct(s1+1, s1+(idx-s2), s2, idx-1)
一行即可。
6)有两种特殊情况需要考虑:没有左子树、没有右子树,即两个if
条件。
3、思路
思路很简单,输入、构造结点、输出,但是构造结点时的细节很多。
4、代码
#include <iostream>
#include <string>
using namespace std;
#define N 20
class Node
{
public:
char value;
Node *lchild;
Node *rchild;
Node()
{
lchild=NULL;
rchild=NULL;
}
};
Node root,node[N];
int pos=0;//记录node[N]的位置
void postOrder(Node *node)
{
if(node->lchild!=NULL)
{
postOrder(node->lchild);
}
if(node->rchild!=NULL)
{
postOrder(node->rchild);
}
cout<<node->value;
}
Node construct(string preOrder,string inOrder)
{
Node n;
n.value=preOrder[0];
if(preOrder.length()==1 && inOrder.length()==1)
{
n.lchild=NULL;
n.rchild=NULL;
}
else
{
string preOrder_left,inOrder_left,preOrder_right,inOrder_right;
string::size_type idx;
Node a;
idx = inOrder.find(preOrder[0]);
if(idx != 0)
{
inOrder_left = inOrder.substr(0,idx);
preOrder_left = preOrder.substr(1,inOrder_left.length());
a=construct(preOrder_left,inOrder_left);
node[pos].value = a.value;
node[pos].lchild = a.lchild;
node[pos].rchild = a.rchild;
n.lchild=&node[pos++];
}
if(idx!=inOrder.length()-1)
{
inOrder_right = inOrder.substr(idx+1);
preOrder_right = preOrder.substr(inOrder_left.length()+1);
a=construct(preOrder_right,inOrder_right);
node[pos].value = a.value;
node[pos].lchild = a.lchild;
node[pos].rchild = a.rchild;
n.rchild=&node[pos++];
}
}
return n;
}
int main()
{
string preOrder,inOrder;
cin>>preOrder>>inOrder;
root = construct(preOrder,inOrder);
postOrder(&root);
return 0;
}