数据结构线段树入门

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构线段树入门相关的知识,希望对你有一定的参考价值。

线段树是一种二叉搜索树。

它将一个区间划分成一些子区间,每个子区间对应线段树中的一个叶节点。

对于线段树中的每一个非叶子节点[a,b],它的左儿子表示的区间为[a,(a+b)>>1],右儿子表示的区间为[(a+b)>>1+1,b]。也就是说线段树是一棵平衡二叉树。

下图是对于[1,10]的区间构造的一棵线段树。

技术分享

 

 

线段树的基本操作函数有三个。

分别是build(建树),update(更新),query(查询区间和)。

 

线段树定义:

struct node{
    int left,right;    //左子树和右子树
    int sum;    //节点区间和
}tree[MAX_N];

 

线段树建树:

void build(int l,int r,int num)
{
    tree[num].left=l;   
    tree[num].right=r;
    if(l==r) return;    //叶子节点 
    int mid=(l+r)>>1;    //二分建树
    build(l,mid,num<<1);    //递归建立左子树
    build(mid+1,r,num<<1|1);    //递归建立右子树
} 

 

线段树更新:

void update(int l,int r,int value,int num)
{
    //叶子节点
    if(tree[num].left==tree[num].right) 
        return;
    int mid=(tree[num].left+tree[num].right)>>1;
    //如果所要更新的点的右端小于mid或左端点大于mid,则直接更新l到r的值
    if(r<=mid) update(l,r,value,num<<1);
    else if(l>mid) update(l,r,value,num<<1|1);
    //如果要更新的点在mid两边,则两边分别更新 
    else{
        update(l,mid,value,num<<1);
        update(mid+1,r,value,num<<1|1);
    }
} 

 

线段树查询:

int query(int l,int r,int num)
{
    //叶子节点
    if(l==tree[num].left && r==tree[num].right) return tree[num].sum;
    int mid=(tree[num].left+tree[num].right)>>1;
    //和更新类似
    if(r<=mid) return query(l,r,num<<1);
    if(l>mid) return query(l,r,num<<1|1);
    else return query(l,mid,num<<1)+query(mid+1,r,num<<1|1);
}

 

线段树应用:连续区间动态查询,连续区间统计等。

时间复杂度:基本保证每个操作为O(logN)。


以上是关于数据结构线段树入门的主要内容,如果未能解决你的问题,请参考以下文章

数据结构线段树入门

比较简单的线段树入门

超全面的线段树:从入门到入坟

线段树——入门学习(java代码实现)

线段树——入门学习(java代码实现)

线段树——入门学习(java代码实现)