【算法】构造数组的MaxTree,构建大根树

在这里插入图片描述

思路:

每个节点的父节点,都是他左边比他大的第一个值,和右边比他大的第一个值中的最小数,既:
M i n ( 左 边 第 一 个 比 X 大 的 值 , 右 边 第 一 个 比 X 大 的 值 ) Min(左边第一个比X大的值,右边第一个比X大的值) Min(XX)
因为

具体原因可以看书,《程序员面试指南 左》第23页

c++:

#include <iostream>
#include<vector>
using namespace std;
struct BiTreeNode {
    int nValue;
    BiTreeNode* pLeft;
    BiTreeNode* pRight;
};


/**
   获取当前节点距离最近的那个较大的值的节点
**/
BiTreeNode* GetMaxInRange(vector<BiTreeNode*>& nodes, int start, int end, BiTreeNode *pNow) {
    BiTreeNode* p = nullptr;
    int max = pNow->nValue, data = 0;
    if (end>pNow->nValue)
    {
        for (int i = start; i <= end; i++)
        {
            data = nodes[i]->nValue;
            if (max < data)
            {
                p = nodes[i];
                return p;
            }
        }
    }
    else {
        for (int i = end; i >=start ; i--)
        {
            data = nodes[i]->nValue;
            if (max < data)
            {
                p = nodes[i];
                return p;
            }
        }
    }
    return p;
}

/*****
    设置父节点的孩子
***/
void SetBiNode(BiTreeNode* son, BiTreeNode* father) {
    if (father && father->pLeft==nullptr)
    {
        father->pLeft = son;
    }
    else if (father&& father->pRight==nullptr)
    {
        father->pRight = son;
    }
    else if(father){
        cout << "异常!父亲节点已经满了!!!还试图往里面加!!不应如此";
    }
    else {
        cout << "异常输入!!!";
    }
}
/***********
*  创建大根数 
****/
BiTreeNode* CreateMaxTree(int* data, int length) {
    if (data == nullptr || length <= 0) {
        return nullptr;
    }
    vector<BiTreeNode*> nodes;
    BiTreeNode* pMax = nullptr;
    int max = 0;
    // 建立树指针数组
    for (int i = 0; i < length; i++)
    {
        BiTreeNode *p=new BiTreeNode();  //动态分配内存
        if (max<data[i])
        {
            max = data[i];
            pMax = p;
        }
        p->nValue = data[i];
        p->pLeft = nullptr;
        p->pRight = nullptr;
        nodes.push_back(p);
    }
    BiTreeNode* pLeft = nullptr;
    BiTreeNode* pRight = nullptr;
    for (int i = 0; i < length; i++)
    {
        pLeft = GetMaxInRange(nodes, 0, i-1,nodes[i]);
        pRight = GetMaxInRange(nodes, i+1, length-1,nodes[i]);
        if (pLeft&&pRight)//11
        {
            if ( pLeft->nValue > pRight->nValue)
            {
                SetBiNode(nodes[i], pRight); // 设置较小的比当前节点大的值为父节点
            }
            else {
                SetBiNode(nodes[i], pLeft);
            }
        }
        else if (pLeft) {
            SetBiNode(nodes[i], pLeft);
        }
        else if (pRight)
        {
            SetBiNode(nodes[i], pRight);
        }
    }
    return pMax;
}


//前序遍历打印检查
void PrePrint(BiTreeNode* pRoot) {
    if (pRoot==nullptr)
    {
        return;
    }
    else {
        cout << pRoot->nValue<<" ";
        PrePrint(pRoot->pLeft);
        PrePrint(pRoot->pRight);
    }

}
int main()
{
    // 5,4,3,2,1
    int data[]={ 3,4,5,1,2 };
    PrePrint(CreateMaxTree(data, 5));
    cout << endl;

    //7,6,3,1,2,5
    int data2[] = { 1,3,2,6,7,5 };
    PrePrint(CreateMaxTree(data2, 6));
    cout << endl;
    //9,4,3,2,1,8,6,5,7
    int data3[] = { 2,3,1,4,9,5,6,8,7 };
    PrePrint(CreateMaxTree(data3, 9));
    cout << endl;

    
    // 10,1,8,7,6
    int data4[] = {1,10,8,7,6 };
    PrePrint(CreateMaxTree(data4, 5));
    cout << endl;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值