2.3 二叉树(一篇血的教训!!!)

二叉树遍历

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

原创文章 35 获赞 17 访问量 7832

猜你喜欢

转载自blog.csdn.net/dear_jing/article/details/105955366
2.3