线段树的实现(模板)

 

线段树

在一类问题中,我们需要经常处理可以映射在一个坐标轴上的一些固定线段,例如说映射在OX轴上的线段。由于线段是可以互相覆盖的,有时需要动态地取线段的并,例如取得并区间的总长度,或者并区间的个数等等。一个线段是对应于一个区间的,因此线段树也可以叫做区间树。

线段树的构造思想

线段树是一棵二叉树,树中的每一个结点表示了一个区间[a,b]。每一个叶子节点表示了一个单位区间。对于每一个非叶结点所表示的结点[a,b],其左儿子表示的区间为[a,(a+b)/2],右儿子表示的区间为[(a+b)/2,b]

 

线段树的运用

线段树的每个节点上往往都增加了一些其他的域。在这些域中保存了某种动态维护的信息,视不同情况而定。这些域使得线段树具有极大的灵活性,可以适应不同的需求。

线段树的实现(完全二叉树)

数据结构

type

    TreeNode = record

    b, e: Integer;

    cover: Integer;

end;

插入算法

procedure Insert(p, a, b: Integer);

var

   m: Integer;

begin

    if Tree[p].cover = 0 then

    begin

        m := (Tree[p].b + Tree[p].e) div 2;

        if (a = Tree[p].b) and (b = Tree[p].e) then

           Tree[p].cover := 1

        else if b <= m then Insert(p * 2, a, b)

        else if a >= m then Insert(p * 2 + 1, a, b)

        else begin

           Insert(p * 2, a, m);

           Insert(p * 2 + 1, m, b);

        end;

    end;

end;

统计算法

function Count(p: Integer): Integer;

begin

    if Tree[p].cover = 1 then

       Count := Tree[p].e – Tree[p].b

    else if Tree[p].e – Tree[p].b = 1 then Count := 0

    else Count := Count(p * 2) + Count(p * 2 + 1);

end;

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值