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的浪费 问题,暂时不在乎)

  • 相关阅读:
    Android自定义之仿360Root大师水纹效果
    Android之TextView的Span样式源码剖析
    Android之TextView的样式类Span的使用详解
    随着ScrollView的滑动,渐渐的执行动画View
    仿微信主界面导航栏图标字体颜色的变化
    android自定义之 5.0 风格progressBar
    Android性能优化之内存篇
    Android性能优化之运算篇
    How to install Zabbix5.0 LTS version with Yum on the CentOS 7.8 system?
    How to install Zabbix4.0 LTS version with Yum on the Oracle Linux 7.3 system?
  • 原文地址:https://www.cnblogs.com/zach0812/p/13399624.html
Copyright © 2011-2022 走看看