二叉树.u122给坐标建树

给定一些坐标点建树

网上看的,自己不会写,代码挺晕的

#include <iostream>

#include <list>

#include <string>

#include <sstream>

using namespace std;

//节点结构体,存储节点的值及左右子节点

struct NODE

{

    int nVal;

    NODE *pL;

    NODE *pR;

}

//NullNode为空节点标本

const NullNode = {0, 0, 0};

//删除树

void DeleteTree(NODE *pPar)

{

    if (pPar != NULL)

    {

        //深度遍例删除左右子节点

        DeleteTree(pPar->pL), DeleteTree(pPar->pR);

    }

    delete pPar;

}

//为树增加节点

NODE* AddChild(NODE *pPar, int nVal, const char *pPath)

{

    //如果父为空,则建立父节点

    if (pPar == 0)

    {

        pPar = new NODE(NullNode);

    }

        //根据当前路径字符串做不同操作

         switch (*pPath)

         {

                 //遇到右括号,说明路径结束,为当前父节点赋值

             case ')': pPar->nVal = (pPar->nVal == 0 && nVal != 0) ? nVal : -1;

                 break;

                 //继续建立左/右子节点

             case 'L': pPar->pL = AddChild(pPar->pL, nVal, pPath + 1);

                 break;

             case 'R': pPar->pR = AddChild(pPar->pR, nVal, pPath + 1);

                 break;

         }

    return pPar;

}

//主函数

int main(void)

{

        //树的根结点

    NODE *pRoot = 0;

        //循环处理输入的每一个节点数据

    for (string strToken; cin >> strToken;)

    {

                //获得节点数据字符串指针

        const char *pStr = strToken.c_str();

        int nLen = strToken.length(), nVal = 0;

        //如果第二个字符不是右括号,则添加节点后继续输入

        if (pStr[1] != ')')

        {

            //将字符串转为数字

            for (; isdigit(*++pStr); nVal = nVal * 10 + *pStr - '0');

            if (*pStr != ',')

            {

                while(true);

                //在树中添加该节点

                pRoot = AddChild(pRoot, nVal, ++pStr);

                continue;

            }

            //如果第二字符是右括号,说明一棵树输入结束,进行遍例

            list<NODE*> Level(1, pRoot);

            stringstream ssResult;

            //依次遍例每一层。用Level存储一层的节点,Level非空则继续遍例

            for (list<NODE*>::iterator i = Level.begin(); !Level.empty();

                 //如果一层遍例结束,则回到起点

                 i = (i == Level.end() ? Level.begin() : i))

                 {

                    //移除当前节点

                    NODE *pTemp = *i;

                    i = Level.erase(i);

                        //如果该节点为空,则直接继续进行下一个节点

                    if (pTemp == 0)

                    {

                        continue;

                    }//否则在原位置上增加子节点

                    //如果该节点的值小于或等于0,说明其重复定义或未定义

                    if (pTemp->nVal <= 0)

                    {

                                //清空数据,返回错误。

                        Level.clear();

                        ssResult.str("");

                        break;

                    }

                    //正确的结点

                        //输入其值,并在原位置上插入其子节点

                    ssResult << pTemp->nVal << ' ';

                    i = Level.insert(i, pTemp->pL), ++i;

                    i = Level.insert(i, pTemp->pR), ++i;

                }

                //删除原树,避免内存泄露。

                DeleteTree(pRoot);

                pRoot = 0;

                strToken = ssResult.str();

                //如果结果为空,说明所给数据有错

                if (strToken.empty())

                {

                    strToken = "not complete";

                } //对于正确结果要去掉最后的一个空格

                else

                {

                    strToken.erase(strToken.end() - 1);

                }

                //输出结果

            cout << strToken << endl;

        }

        return 0;

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值