zoukankan      html  css  js  c++  java
  • 01玩转数据结构_09_线段树Segment Tree(区间树)

    什么是线段树

    概念

    线段树是一种二元树形数据结构,1977年由Jon Louis Bentley发明,用以储存区间或线段,并且允许快速查询结构内包含某一点的所有区间。

    一个包含 n 个区间的线段树,空间複杂度为,查询的时间複杂度则为,其中      ,  其中k是符合条件的区间数量。

    引例:

    假设某大学有一面文化墙,各个学院都可以在上面涂色,要求涂色区域高必须和墙一样,宽度任意但必须是整数(以米为单位)。涂色可以覆盖其他学院的涂色。现在若干个学院涂色之后最终这面墙上能看见多少种颜色。

    抽象出来就是m次操作后,我们可以在【i,j】 区间看见多少中颜色?

    这个过程是两种操作:

    1,染色(更新区间):改变区间的值

    2,查询操作:查询指定区间的颜色数

    当然可以用数组实现,时间复杂度 = O(n) + O(n) = O(n),显然不是很好的方案,

    线段树在这里就很适合,这时时间复杂度都可以O(logn)

    举例:

    所以,线段树可能不是满的二叉树,也可能不是完全二叉树,但是,线段树是平衡二叉树,

    平衡二叉树的简单定义: 

    是一种结构平衡的二叉搜索树,它是一种  每个节点的左右两子树高度差都不超过一  的二元树。它能在O( log n  )内完成插入、查找和删除操作,最早被发明的平衡二叉搜索树为AVL树。

    常见的平衡二叉搜索树有:

    AVL树
    红黑树
    Treap(树堆 tree + heap )
    节点大小平衡树

    表示这颗树的数组大小问题:

    因为线段树是平衡二叉树,所以我们可以用数组来表示它

    如何区间有n个元素,那么数组需要开辟多大呢?

    如果n = 2^k ,数组需要 2*2^k - 1 (等比数列求和 2^0+...+2^k) , 所以要分配2n个。

    如果最坏n = 2^k + 1 ,这时,多余的一个要放到下一层,数组需要4*2^k -1 (等比数列求和 2^0+...+2^k+2^(k+1)  ), 此时造成的浪费最大, (不过无所谓,以空间换时间),所以要分配 4n个。 

    因此,答案就是4n,而且这里区间我们不考虑添加元素,即区间固定,数组只需要4n的静态空间即可,(注:很可能造成2n的浪费 问题,暂时不在乎)

  • 相关阅读:
    为html瘦身的pythonl函数
    python字符编码演示三则
    爬虫任务队列方案以及性能测试
    从一道动态规划到卡特兰数
    LeetCode 24 JAVA
    链表笔记
    KMP 算法
    LeetCode 有效数独 JAVA
    Leetcode 139 单词拆分 JAVA
    Leetcode 845 数组的山脉 JAVA
  • 原文地址:https://www.cnblogs.com/zach0812/p/13399624.html
Copyright © 2011-2022 走看看