重建二叉树

本文介绍了一种通过先序遍历和中序遍历来重建二叉树的方法,并提供了详细的算法实现步骤及代码示例。

对于一颗二叉树,可以根据先序遍历(后序遍历)和中序遍历重新还原出二叉树。

根据先序遍历和中序遍历还原二叉树的主要思想:

1、先序遍历序列的第一个元素必定是根节点,可以由此获取二叉树的根节点。

2、根据根节点,在中序遍历序列中查找该节点,由中序遍历的性质可知,中序遍历中该根节点左边的序列必定在根节点的左子树中,而根节点右边的序列必定在右子树中。由此可以知道先序遍历中左子树以及右子树的起止位置。

3、分别对左子树和右子树重复上述的过程,直至所有的子树的起止位置相等时,说明已经到达叶子节点,遍历完毕。

代码如下:


#ifndef __FUNCTION_H__
#define __FUNCTION_H__
#include <iostream>

using namespace std;
struct BinaryTreeNode
{
    int nodeValue;
    BinaryTreeNode *pLeft;
    BinaryTreeNode *pRight;
};

BinaryTreeNode * BuildRecursivly(int *pPrevOrderStart, int *pPrevOrderEnd, int *pInOrderStart, int *pInOrderEnd)
{
    //在先序遍历序列中取出第一个元素即为根节点元素
    int value = pPrevOrderStart[0];
    //构造根节点
    BinaryTreeNode *root = new BinaryTreeNode;
    root->nodeValue = value;
    root->pLeft = root->pRight = NULL;
    //递归结束的情况,即只剩一个叶子节点
    if(pPrevOrderStart == pPrevOrderEnd)
    {
        if(pInOrderStart == pInOrderEnd && *pPrevOrderStart == *pInOrderStart)
            return root;
        else
            throw std::exception();
    }
    //在中序遍历序列中找出根节点的位置
    int *pInOrderCursor = pInOrderStart;
    while(pInOrderCursor < pInOrderEnd && *pInOrderCursor != value)
    {
        pInOrderCursor++;
    }
    if(pInOrderCursor == pInOrderEnd && *pInOrderCursor != value)
    {
        throw std::exception();
    }
    //取得左子树的长度以及在先序遍历中取得左子树的起始位置
    int leftTreeLen = pInOrderCursor - pInOrderStart;
    int *pPrevOrderLeftTreeEnd = pPrevOrderStart + leftTreeLen;
    //如果左子树存在,则递归左子树
    if(leftTreeLen > 0)
    {
        root->pLeft = BuildRecursivly(pPrevOrderStart+1, pPrevOrderLeftTreeEnd,
                                      pInOrderStart, pInOrderCursor-1);
    }
    //如果右子树存在,则递归右子树
    if((pPrevOrderEnd-pPrevOrderStart) > leftTreeLen)
    {
        root->pRight = BuildRecursivly(pPrevOrderLeftTreeEnd+1, pPrevOrderEnd,
                                       pInOrderCursor+1, pInOrderEnd);
    }

    return root;
}

BinaryTreeNode * BulidBinaryTree(int *szPrevOrder, int *szInOrder, int nodeNum)
{
    if(szPrevOrder == NULL || szInOrder == NULL)
        return NULL;
    return BuildRecursivly(szPrevOrder, szPrevOrder+nodeNum-1,
                           szInOrder, szInOrder+nodeNum-1);
}

/*先序遍历*/
void PrevOrder(BinaryTreeNode *root)
{
    if(root == NULL)
        return;
    //根
    cout<<root->nodeValue<<' ';
    //左子树
    if(root->pLeft != NULL)
        PrevOrder(root->pLeft);
    //右子树
    if(root->pRight != NULL)
        PrevOrder(root->pRight);
}

/*中序遍历*/
void InOrder(BinaryTreeNode *root)
{
    if(root == NULL)
        return;
    //左子树
    if(root->pLeft != NULL)
        InOrder(root->pLeft);
    //根
    cout<<root->nodeValue<<' ';
    //右子树
    if(root->pRight != NULL)
        InOrder(root->pRight);
}

/*后序遍历*/
void PostOrder(BinaryTreeNode *root)
{
    if(root == NULL)
        return;
    //左子树
    if(root->pLeft != NULL)
        PostOrder(root->pLeft);
    //右子树
    if(root->pRight != NULL)
        PostOrder(root->pRight);
    //根
    cout<<root->nodeValue<<' ';
}

#endif

主函数:

#include <iostream>
#include "function.h"

using namespace std;

/*重建二叉树*/
int main()
{
    int szPrevOrder[] = {1, 2, 4, 7, 3, 5, 6, 8};   //二叉树的先序遍历
    int szInOrder[] = {4, 7, 2, 1, 5, 3, 8, 6};     //二叉树的中序遍历
    int nodeNum = sizeof(szPrevOrder)/sizeof(int);
    BinaryTreeNode *root = BulidBinaryTree(szPrevOrder, szInOrder, nodeNum);
    cout<<"PrevOrder: ";
    PrevOrder(root);
    cout<<endl<<"InOrder:   ";
    InOrder(root);
    cout<<endl<<"PostOrder: ";
    PostOrder(root);
    cout<<endl;

    return 0;
}


计及风电并网运行的微电网及集群电动汽车综合需求侧响应的优化调度策略研究(Matlab代码实现)内容概要:本文研究了计及风电并网运行的微电网及集群电动汽车综合需求侧响应的优化调度策略,并提供了基于Matlab的代码实现。研究聚焦于在高渗透率可再生能源接入背景下,如何协调微电网内部分布式电源、储能系统与大规模电动汽车充电负荷之间的互动关系,通过引入需求侧响应机制,建立多目标优化调度模型,实现系统运行成本最小化、可再生能源消纳最大化以及电网负荷曲线的削峰填谷。文中详细阐述了风电出力不确定性处理、电动汽车集群充放电行为建模、电价型与激励型需求响应机制设计以及优化求解算法的应用。; 适合人群:具备一定电力系统基础知识和Matlab编程能力的研究生、科研人员及从事新能源、微电网、电动汽车等领域技术研发的工程师。; 使用场景及目标:①用于复现相关硕士论文研究成果,深入理解含高比例风电的微电网优化调度建模方法;②为开展电动汽车参与电网互动(V2G)、需求侧响应等课题提供仿真平台和技术参考;③适用于电力系统优化、能源互联网、综合能源系统等相关领域的教学与科研项目开发。; 阅读建议:建议读者结合文中提供的Matlab代码进行实践操作,重点关注模型构建逻辑与算法实现细节,同时可参考文档中提及的其他相关案例(如储能优化、负荷预测等),以拓宽研究视野并促进交叉创新。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值