线段树的构造

题目描述:线段树是一棵二叉树,他的每个节点包含了两个额外的属性start和end用于表示该节点所代表的区间。start和end都是整数,并按照如下的方式赋值:

根节点的 start 和 end 由 build 方法所给出。

对于节点 A 的左儿子,有 start=A.left, end=(A.left + A.right) / 2。

对于节点 A 的右儿子,有 start=(A.left + A.right) / 2 + 1, end=A.right。

如果 start 等于 end, 那么该节点是叶子节点,不再有左右儿子。

实现一个 build 方法,接受 start 和 end 作为参数, 然后构造一个代表区间 [start, end] 的线段树,返回这棵线段树的根

样例:

比如给定start=1, end=6,对应的线段树为:

对于这样一棵树的所有节点来说,不过是两种情况:1. 非叶节点,那么这个通过这个节点,我们就能得到它的左右孩子的所存储的“区间值”。2. 叶子节点,那就直接返回这个节点就行

所以,这是非常经典的递归的应用,触底的条件是start > end,返回空,或者start == end,返回叶子节点。

直接上代码:

"""
Definition of SegmentTreeNode:
class SegmentTreeNode:
    def __init__(self, start, end):
        self.start, self.end = start, end
        self.left, self.right = None, None
"""

class Solution:
    # @param start, end: Denote an segment / interval
    # @return: The root of Segment Tree
    def build(self, start, end):

        # 起点大于终点,返回空
        if start > end:
            return 

        # 起点等于终点,返回叶子
        if start == end:
            return SegmentTreeNode(start, end)

        # 生成根节点
        root = SegmentTreeNode(start, end)
        mid = (end + start) // 2

        # 递归生成每个节点的左右孩子
        root.left = self.build(start, mid)
        root.right = self.build(mid + 1, end)
        return root
        # write your code here
时间: 2024-10-13 12:50:14

线段树的构造的相关文章

HDU 5820 (可持久化线段树)

Problem Lights (HDU 5820) 题目大意 在一个大小为50000*50000的矩形中,有n个路灯.(n<=500000) 询问是否每一对路灯之间存在一条道路,使得长度为|x1 – x2| + |y1 – y2|且每个拐弯点都是路灯. 解题分析 官方题解: 除了从左往右扫描一遍外,个人认为还需从右往左扫描一遍,记录右上方的点的信息. 实际实现时,只需将整个图左右对称翻转一下即可. 学习了一下可持久化线段树的正确姿势. 可持久化线段树的空间一定要开大,开大,开大. 下图为模拟的小

线段树入门理解

在复习算法至分治法时,书本上主要介绍了合并排序和快速排序,较为简单.特拓展简单学习一个应用了分治法的算法结构--线段树. acm刷题时遇到许多连续区间的动态查询问题,例如求取某一区间上元素之和.求取某一区间上元素的最大值,此时如果使用一般的方法求解会使得时间超出要求.此时需要使用到线段树,其主要用于高效解决连续区间的动态查询问题. 线段树,类似区间树,是一个完全二叉树,它在各个节点保存一条线段(数组中的一段子数组),由于二叉结构的特性,它基本能保持每个操作的复杂度为O(lgN),从而大大减少耗时

线段树——持续更新辣

一:线段树的基本概念 1:概述 线段树,类似区间树,是一个完全二叉树,它在各个节点保存一条线段(数组中的一段子数组),主要用于高效解决连续区间的动态查询问题,由于二叉结构的特性,基本能保持每个操作的复杂度为O(log n)性质:假设某节点对应的区间是[a,b],设c=(a+b)/2,则左子树对应的区间是[a,c],右子树对应的区间是[c+1,b],线段树空间复杂度为O(n); 2:维护点及点修改的线段树 (1)构造线段树 函数:build(int begin,int end,int node)

数据结构---线段树

线段树 转载请注明出处,谢谢!http://blog.csdn.net/metalseed/article/details/8039326  持续更新中···   一:线段树基本概念 1:概述 线段树,类似区间树,是一个完全二叉树,它在各个节点保存一条线段(数组中的一段子数组),主要用于高效解决连续区间的动态查询问题,由于二叉结构的特性,它基本能保持每个操作的复杂度为O(lgN)! 性质:父亲的区间是[a,b],(c=(a+b)/2)左儿子的区间是[a,c],右儿子的区间是[c+1,b],线段树

线段树入门(poj 3274 3468 2528)

概念: 在一类问题中,我们需要经常处理可以映射在一个坐标轴上的一些固定线段,例如说映射在OX轴上的线段.由于线段是可以互相覆盖的,有时需要动态地取线段的并,例如取得并区间的总长度,或者并区间的个数等等.一个线段是对应于一个区间的,因此线段树也可以叫做区间树. 线段树常用于区间多次插入查询,经常改变数据. 而线段树的核心在于如何设计一个节点的信息 这里针对线段树的应用有三个方面: 1. 每次查询一个区间的最大差值(结点存放这个区间的最大最小值 3274) 2.不断修改区间内的数值,并查询区间的和

poj2528线段树解题报告,离散化+线段树

题目网址:http://poj.org/problem?id=2528 题意: n(n<=10000)个人依次贴海报,给出每张海报所贴的范围li,ri(1<=li<=ri<=10000000). 求出最后还能看见多少张海报. 输入: 1 5 1 4 2 6 8 10 3 4 7 10 这题用常规思路解题必定TLE,l,r太大: 通俗点说,离散化就是压缩区间,使原有的长区间映射到新的短区间,但是区间压缩前后的覆盖关系不变.举个例子: 有一条1到10的数轴(长度为9),给定4个区间[2

线段树+离散化的资料(写的很好)

1.  线段树是二叉树,且必定是平衡二叉树,但不一定是完全二叉树. 2.  对于区间[a,b],令mid=(a+b)/2,则其左子树为[a,mid],右子树为[mid+1,b],当a==b时,该区间为线段树的叶子,无需继续往下划分. 3.  线段树虽然不是完全二叉树,但是可以用完全二叉树的方式去构造并存储它,只是最后一层可能存在某些叶子与叶子之间出现“空叶子”,这个无需理会,同样给空叶子按顺序编号,在遍历线段树时当判断到a==b时就认为到了叶子,“空叶子”永远也不会遍历到. 4.  之所以要用完

线段树の一 区间和

线段树の一 区间和 具体线段树讲解:(搬运)http://blog.csdn.net/zearot/article/details/48299459 一:线段树基本概念 1:概述 线段树,类似区间树,是一个完全二叉树,它在各个节点保存一条线段(数组中的一段子数组),主要用于高效解决连续区间的动态查询问题,由于二叉结构的特性,它基本能保持每个操作的复杂度为O(lgN)! 性质:父亲的区间是[a,b],(c=(a+b)/2)左儿子的区间是[a,c],右儿子的区间是[c+1,b],线段树需要的空间为数

poj-----(2528)Mayor&#39;s posters(线段树区间更新及区间统计+离散化)

Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 43507   Accepted: 12693 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral post