`

线段树(二)——时间、空间复杂度

 
阅读更多

参考文章:

《在一维数组中以完全二叉树方式存储线段树的空间分析》 http://comzyh.tk/blog/archives/479/

《线段树简介与简单应用》http://hi.baidu.com/etwge/blog/item/c6c2dff887d2eb909f514664.html

 

我们大家存储线段树的方式无非两种:

  1. 二叉链表
  2. 一维数组完全二叉树

二叉链表优点是节省空间,缺点是编程复杂度大,执行效率较低,空间复杂度为2N

在一维数组以完全二叉树方式存储线段树的编程复杂度小,执行效率较高,但浪费空间
长期以来,我和我校的OIer一直不知以一维方式存储线段树到底需要开多大的数组.今天正好有些闲暇的时间,写了个小程序,分析了下一维线段树在一维方式存储下到底需要占用多少空间.经本文所述方式计算约为4N

 

先来补习一下完全二叉树的相关知识:
完全二叉树在一维数组中这样表示:根节点为1,其左子树为2,右子树为3.
根节点为N,其左孩子为2N,右孩子为2N+1
具体实现方式可参考我的一篇题解 ,这里使用的就是完全二叉树方式

像线段树这样区间长度并不一定是 2^{n} 的二叉树,其占用空间为 2的(最深线段的深度)次幂,就给线段树的空间占用造成了很大的不确定性.在我们学校,关于线段树的空间占用,说法大致有以下几种

  • 极端保守的:10N
  • 保守(我):5N
  • 乐观:3N
  • 极乐观:2N

然而大家写的是后大部分都是尽量多开,对于其空间占用一直没有定论,现在我来给个定论:

先上一幅图:


可以看到,空间复杂度其实是最好\Theta(2N) ,最差是\Theta(4N) ,最好情况出现在略小于2^{k} 附近,最坏情况出现在略大于2^{k} 附近,由此看来,我们以后存线段树大概需要开4N+100 的数组就可以了.

 

关于\Theta(4N) ,思考一下代表总区间[1,L]的线段树需要多少个节点即可(tips: 不断二分,上限是一棵满二叉树; conclusion: 空间<2^0+2^1+...+2^(1+log(L-1))=4(L-1)-1

 

附线段树空间计算程序:

输入区间长度,他来告诉你要开多大数组.

/*注:这是一棵离散型的线段树*/
#include <iostream>
//#include <cstdio>
//#include <cstdlib>
using namespace std;

struct segment {
       int b,e;
};
segment seg[5000000];
int N;		//线段树对应的总区间长度1,2,...,N
int Nnode;	//线段树中一共有多少结点(这棵线段树基本上是平衡的二叉树,但不一定是完全二叉树)
int LastNode;	//线段树中最后一个结点的序号

void build(int b, int e, int s);

int main(){
    while (1){
          printf("Please Enter Interval length 请输入区间长度:\n");
          scanf("%d",&N);
          if (N==0)return 0;
          Nnode=0;
          LastNode=0;
          build(1,N,1);
          printf("Complete binary tree, has build %d Nodes ,the last node numbered %d\n %d 最后一个节点:%d\n",Nnode,LastNode,Nnode,LastNode);
          //system("pause");
          }
}
void build(int b, int e, int s){
     Nnode++;
     if (s>LastNode)
        LastNode=s;
     seg[s].b=b;
     seg[s].e=e;
     if (b==e)
         return;
     int mid =(b+e)>>1;
     build(b,mid,s<<1);
     build(mid+1,e,(s<<1)+1);
}
 

附线段树空间占用分析程序(打表),上面那个图的表就是它计算出来的:

/*线段树空间分析程序 Power By:Comzyh*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
struct segment {
       int b,e;
       };
segment seg[5000000];
int N;
int Nnode,LastNode;
void build(int b, int e, int s);
int main(){
    freopen ("segmentCount.csv","w",stdout);
    int i=1;
    scanf("%d",&N);
    printf("区间长度,节点数,最后一个节点编号\n");
    while (N-i>=0){
          Nnode=0;
          LastNode=0;
          build(1,i,1);
          printf("%d,%d,%d\n",i,Nnode,LastNode);
          
          i++;
          }
    //system("pause");
    }
void build(int b, int e, int s){
     Nnode++;
     if (s>LastNode)
        LastNode=s;
     seg[s].b=b;
     seg[s].e=e;
     if (b==e)
         return;
     int mid =(b+e)>>1;
     build(b,mid,s<<1);
     build(mid+1,e,(s<<1)+1);
     }

 

然后打了个表,可以用来查询线段树空间

区间长度  ,占用空间 
         1:1
         2:3
         3:5
         4:7
         5:9
         6:13
         7:13
         8:15
         9:17
        10:25
        10:25
        20:57
        30:61
        40:121
        50:125
        60:125
        70:225
        80:249
        90:249
       100:253
       200:509
       300:1009
       400:1021
       500:1021
       600:2033
       700:2041
       800:2045
       900:2045
      1000:2045
      2000:4093
      3000:8185
      4000:8189
      5000:16369
      6000:16377
      7000:16381
      8000:16381
      9000:32737
     10000:32753
     20000:65521
     30000:65533
     40000:131057
     50000:131069
     60000:131069
     70000:262113
     80000:262129
     90000:262137
    100000:262141
    200000:524285
    300000:1048561
    400000:1048573
    500000:1048573
    600000:2097137
    700000:2097145
    800000:2097149
    900000:2097149
   1000000:2097149
   2000000:4194301
   3000000:8388601
   4000000:8388605
   5000000:16777201
   6000000:16777209
   7000000:16777213
   8000000:16777213
   9000000:33554401
  10000000:33554417
 

 

 

  • 大小: 18.2 KB
分享到:
评论

相关推荐

    线段树和树状数组——北京大学暑期课《ACM/ICPC竞赛训练》

    - 树状数组的空间复杂度为`O(n)`,时间复杂度为`O(log n)`。 - 与线段树相比,树状数组在实现上更简单,占用空间更少。 **应用场景:** - 区间求和。 - 频率统计。 #### 总结 线段树和树状数组是解决区间查询和...

    解决动态统计问题的两把利刃——剖析线段树与矩形切割_薛矛.ppt

    线段树的复杂性分析表明,构造线段树的时间复杂度为O(n log n),n是线段的数量。查询和单点修改操作的时间复杂度为O(log n),区间修改操作通常需要O(log^2 n)时间。这些性能使得线段树成为处理动态统计问题的强大...

    线段树资料

    - **存储效率**:线段树的空间复杂度为`O(n)`,其中`n`为原始数组的长度。 - **操作效率**:线段树可以在线性对数时间内完成查询和更新操作,即`O(log n)`。 **1.3 定理** 定理1:线段树能将区间上的任意一条线段...

    运用伸展树解决数列维护问题 by Crash

    伸展树是一种自平衡的二叉搜索树,它可以在O(log n)的时间复杂度内完成查找、插入和删除等操作,并且具有独特的特性——伸展操作,使得最近访问过的节点容易再次被访问。在数列维护问题中,伸展树能够提供比线段树更...

    《1全国计算机等级考试——二级公共基础知识》辅导讲义---第一章 数据结构与算法.doc

    然后,讨论了算法的复杂度,包括时间复杂度和空间复杂度。之后,介绍了数据结构的基本概念,包括数据结构的定义、逻辑结构、存储结构和运算等。最后,讨论了数据结构的图形表示、线性结构和非线性结构等。 算法是指...

    复杂度证明1

    这里我们讨论的"复杂度证明1"涉及到的是一个特定的算法,它利用了数据结构——线段树,并着重于处理区间赋值和查询操作的复杂度。 线段树是一种自顶向下的平衡树结构,用于高效地支持区间查询和更新操作。在这个...

    高级数据结构-----刘汝佳

    以上就是《高级数据结构》一书中所介绍的关键知识点,涵盖了平衡二叉树、可并优先队列、线段树和树状数组的基础知识以及RMQ和LCA问题的解决方案。这些知识点不仅对ACM竞赛有着重要的作用,也是实际软件开发中非常...

    数据结构(java语言描述)

    此外,空间复杂度也被提及,它是指算法执行过程中所需的内存空间,同样反映了算法的效率。 在算法复杂度及其分析部分,邓教授列举了一些常见的复杂度级别,如O(1)、O(logn)和O(n),并用具体的问题来解释这些复杂度...

    二级公共基础辅导讲义.doc

    - **空间复杂度**:评估算法执行过程中所需的内存空间大小。 ### 二、数据结构的基本概念 **数据结构定义:** 数据结构是数据元素间固有逻辑关系及存储关系的集合。 **数据结构的研究方向:** 1. **逻辑结构**:...

    计算机二级公共基础知识

    算法的时间和空间复杂度 - **时间复杂度**:衡量算法执行所需的时间量,通常使用大O符号来表示。 - **空间复杂度**:衡量算法执行过程中所需的存储空间量,同样使用大O符号来表示。 ##### 3. 数据结构基本概念 - ...

    华中科技大学网络空间安全学院-算法设计与分析-内含源码和说明书(可自行修改).zip

    5. **线段树**:线段树是一种数据结构,用于支持区间查询和更新操作,如求区间和、最值等。"线段树"的源码可以帮助学习者深入理解动态区间维护的问题。 6. **网络流**:网络流理论是运筹学的一个分支,用于处理流量...

    真题解析│蓝桥杯省赛真题之油漆面积.pdf

    - 时间复杂度为 O(n * max(x2 - x1, y2 - y1)),但空间复杂度较高。 ##### 高效解法——线段树的扫描线算法 当题目中的数据规模较大时,如 n 或坐标值更大时,上述暴力解法不再适用。此时需要采用更为高效的算法...

    k-d tree资料

    - **空间复杂度**:K-D树的空间复杂度取决于存储的数据量,通常是O(n)。 #### 五、变体 - **替代数据类型**:除了存储点之外,K-D树还可以用于存储其他类型的数据,如线段、矩形等。 - **只在叶子节点存储数据**:...

    算法之路 ,成功掌握各种算法

    - **快速排序**:平均时间复杂度为O(n log n),空间复杂度为O(log n)。 - **堆排序**:利用二叉堆进行排序,时间复杂度为O(n log n)。 - **归并排序**:采用分治策略,时间复杂度为O(n log n)。 通过这两个阶段的...

    IOI国家集训队论文集1999-2019

    + [线段树](#线段树) + [单调队列](#单调队列) + [哈希表](#哈希表) + [Splay](#splay) * [图论](#图论) + [图论](#图论-1) + [模型建立](#模型建立) + [网络流](#网络流) + [最短路](#最短路) + [欧拉路]...

    CCF WC2017 冬令营 课件集合 (圆方树等)

    5. 其他高级算法:除了圆方树,课件可能还包含了如区间树、线段树、二叉堆、并查集等数据结构和算法,这些都是在奥林匹克信息学竞赛(OI)中常见的问题解决工具。 通过学习这些内容,参与者不仅可以提升自己的算法...

    计算几何算法与应用计算几何算法与应用

    9. **几何算法分析**:复杂度理论是计算几何不可或缺的部分,需要了解和评估算法的时间复杂度和空间复杂度。 10. **应用领域**:计算几何广泛应用于图形学、GIS(地理信息系统)、CAD(计算机辅助设计)、机器人...

    考试大论坛:全国计算机二级复习知识点小结(VB卷).doc

    算法的时间复杂度和空间复杂度是衡量其效率的重要指标,前者关注执行算法所需的基本运算次数,后者关注执行算法所需的内存空间。 数据结构是互相关联的数据元素的集合,包括逻辑结构和存储结构两方面。逻辑结构描述...

    计算几何与方法设计

    8. **方法设计**:讨论如何根据具体问题选择合适的算法,如何优化算法性能,如何分析算法的时间复杂度和空间复杂度。 9. **编程实践**:可能会提供一些编程实例,让读者理解如何在实际编程环境中实现计算几何算法。...

    挑战程序设计竞赛(第2版)

    3.3.1 线段树 3.3.2 Binary Indexed Tree 3.3.3 分桶法和平方分割 3.4 熟练掌握动态规划 3.4.1 状态压缩DP 3.4.2 矩阵的幂 3.4.3 利用数据结构高效求解 3.5 借助水流解决问题的网络流 3.5.1 最大流 3.5.2 最小割 ...

Global site tag (gtag.js) - Google Analytics