非递归实现有序数组构建BST

在这里插入图片描述

前置知识

  • BST,就是我们平时说的平衡二叉树。这种树的性质是对于节点root,root左边的所有的子节点的权值都小于这个root的权值,root右边所有子树的权值都大于root的权值。

BST构建的两种方法

递归实现
  • 这种实现方法一般比较方便,思维含量也相对较低。就是根据树的可递归的性质,我们对树进行递归构建,从根开始向叶子结点进行构建,我们利用二分的方法进行处理,当前边界二分之后的终点的权值就是我们当前这个结点的权值了。

  • 代码如下

/**
 * struct TreeNode {
 *	int val;
 *	struct TreeNode *left;
 *	struct TreeNode *right;
 * };
 */

class Solution {
public:
    /**
     * 
     * @param num int整型vector 
     * @return TreeNode类
     */
    TreeNode* createTree(int l,int r,vector<int>& num){
        // 递归的边界
        if(l>r){
            return NULL;
        }
        // 先求中点
        int mid=(l+r)>>1;
        TreeNode* now = new TreeNode(num[mid]);
        now->left=createTree(l,mid-1,num);  // 递归构建左子树
        now->right=createTree(mid+1,r,num);  // 递归构建右子树
        return now;
    }
    TreeNode* sortedArrayToBST(vector<int>& num) {
        // 特判空结点的情况
        if(num.size()==0){
            return NULL;
        }
        return createTree(0,num.size()-1,num);
    }
};

非递归实现
  • 递归的方法相信很多人都会了,但是对于非递归的方法,一般是比较难想到的。
  • 对于非递归的方法,我们一般是采用队列来进行处理,为什么呢?这里我们可以这么理解。我们在进行递归处理的时候,我们发现,我们是先处理完当前这个结点,然后递归到这个结点的左右结点进行处理。先递归到的就先进行处理,这与我们那个数据结构能进行关联呢?对的,就是队列,学过数据结构的同学都知道,队列的性质就是先进先出。那么我们完全可以将我们每次递归需要的参数都放到队列里面,然后按照队列里面元素的先后顺序进行处理,这样,不久可以达到和递归相同的处理了吗?而且我们这种方法不需要使用真的递归,显然是更好的方法。
  • 这里,我们需要用到的是结点指针和左右边界,由于他们的参数类型不一样,所以这里我们使用两个队列来进行处理。
  • 所以,这其实就是一个很经典的BFS模型了,我们先将初始参数放进队列里面,然后,我们一步一步进行拓展即可。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-taitorYc-1652627386771)(/upload/2022/01/image-77a07bd2615d43fd8b81b6382dde1241.png)]

  • 代码如下
/**
 * struct TreeNode {
 *	int val;
 *	struct TreeNode *left;
 *	struct TreeNode *right;
 * };
 */

class Solution {
public:
    /**
     * 
     * @param num int整型vector 
     * @return TreeNode类
     */
    TreeNode* sortedArrayToBST(vector<int>& num) {
        // write code here
        if(num.size()==0){
            return NULL;
        }
        queue<TreeNode*> st_node;
        queue<int> st_index;
        // 初始化根节点
        TreeNode* root = new TreeNode(0);
        st_node.push(root);
        st_index.push(0);
        st_index.push(num.size()-1);
        while(!st_node.empty()){
            // 取出当前这一层结点处理我们需要的参数,主要是左右边界
            int l=st_index.front();st_index.pop();
            int r=st_index.front();st_index.pop();
            int mid=(l+r)>>1;
            TreeNode* now = st_node.front();st_node.pop();
            now->val=num[mid];
            // 拓展左子节点处理需要的参数
            if(l<mid){
                st_index.push(l);
                st_index.push(mid-1);
                TreeNode* tmp = new TreeNode(0);
                root->left=tmp;
                st_node.push(tmp);
            }
            // 拓展右子节点处理需要的参数
            if(r>mid){
                st_index.push(mid+1);
                st_index.push(r);
                TreeNode* tmp = new TreeNode(0);
                root->right=tmp;
                st_node.push(tmp);
            }
        }
        
        return root;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值