Java教程

线段树(待更新)

本文主要是介绍线段树(待更新),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

一种降低时间复杂度的空间储存方法。

 对于一个数组  a[N](这里N=16)

可以采取线段树  tr[N]  的方式储存

方便进行   单点修改、区间查询。

样式图:(1—16:表示存一个在1~16这个区间内的属性)

1———————16
   1 —— 8        9——16
1——45——89——1213——16
1——23——45——67——89——1011——1213——1414——16
1234567810111213141516

接下来是一个完整版子

//  main.cpp
//  线段树
//区间最大值线段树
#include <iostream>
#include <cstring>
#include <math.h>
using namespace std;
#define N 10001
int tr[N*4];//为了从 总数/2 处开始建立
//线段树建立
void build(int rt,int l,int r)
{
    if(l==r)
    {scanf("%d",&tr[rt]);return;}
    int m=(l+r)/2;//取中间值
    build(2*rt,l,m);//建立左子节点
    build(2*rt+1,m+1,r);//建立右子节点
    tr[rt]=max(tr[rt*2],tr[rt*2+1]);//取两个字节点的最大值
}
//更改某一节点的值
void charge(int rt,int l,int r,int u,int num)
{
    if(r==l)
    {tr[rt]=num;return;}
    int m=(l+r)/2;
    if(u<=m)  charge(2*rt,l,m,u,num);//完善左节点
    else      charge(2*rt+1,m+1,r,u,num);//完善右节点
    tr[rt]=max(tr[rt*2],tr[rt*2+1]);//完善树
}
//查找区间最大值
int max_of_query(int rt,int l,int r,int L,int R)
{
    if(L==l && R==r)//判断整体在不在一个完整的区间里
        return tr[rt];//返回该区间的值
    int m=(r+l)/2;
    int maxl=0;//定义最大值
    if(L<=m)
    {
        if(R>m)//判断右端点是否在区间内
            maxl=max(maxl,max_of_query(rt*2,l,m,L,m));
        else
            maxl=max(maxl,max_of_query(rt*2,l,m,L,R));
    }//左子区间
    if(R>=m+1)
    {
        if(L<m+1)//同上
            maxl=max(maxl,max_of_query(rt*2+1,m+1,r,m+1,R));
        else
            maxl=max(maxl,max_of_query(rt*2+1,m+1,r,L,R));
    }//右子区间
    return maxl;
}
//生成树
void see_tree(int tr[])
{
    int i,j=1;
    for(i=1;tr[i]!=0;i++)
    {
        if(i==pow(2,j))
        {printf("\n");j++;}
        printf("%d\t",tr[i]);
    }
}
int main()
{
    int n;
    int u,num;
    int l,r,mx;
    cin>>n;
    
    build(1,1,n);//建立一个从1~n的最大值线段树
    see_tree(tr);
    
    cin>>u>>num;//改位置u上的数为num
    charge(1,1,n,u,num);
    see_tree(tr);
    
    cin>>l>>r;//查找区间(l,r)最大值
    mx=max_of_query(1,1,n,l,r);
    printf("%d",mx);
    //see_tree(tr);
    
    return 0;
}
这篇关于线段树(待更新)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!