`

线段树-入门

阅读更多


/**
 * 线段树入门
 * 问题:已知线段[2,5] [4,6] [0,7];求点2,4,7分别出现了多少次
 * 以下代码建立的线段树用链表来保存,且树的叶子结点类似[i,i]
 * 
 * 参考链接:http://hi.baidu.com/semluhiigubbqvq/item/be736a33a8864789f4e4ad18
 * @author lijinnan
 */
public class SegmentTreeLearn {

    public static void main(String[] args) {
        SegmentTree tree = new SegmentTree(0, 7);
        int[][] segments = {
                {2, 5}, 
                {4, 6}, 
                {0, 7}
        };
        int[] targets = {2, 4, 7};
        for (int i = 0, len = segments.length; i < len; i++) {
            int[] segment = segments[i];
            tree.insert(segment[0], segment[1]);
        }
        for(int target : targets) {
            System.out.println(target + ":" + tree.caculateExistingTimes(target));
        }
    }
    


}

class SegmentTree {

    //递归定义的,因此很多操作都是递归实现
    private class Segment {
        int left;
        int right;
        int count;
        Segment leftChild;
        Segment rightChild;
    }
    
    private Segment root;
    
    public SegmentTree (int left, int right) {
        root = new Segment();
        build(root, left, right);
    }
    
    public void insert(int left, int right) {
        insert(root, left, right);
    }
    
    public int caculateExistingTimes(int target) {
        return caculateExistingTimes(root, target);
    }
    
    //从根节点开始查找叶子结点[target, target],对经过的节点的count求和
    private int caculateExistingTimes(Segment root, int target) {
        int result = 0;
        while( root.left != root.right) {
            int rootMid = root.left + (root.right - root.left) / 2;
            result += root.count;
            if (target <= rootMid) {
                root = root.leftChild;
            } else if (target > rootMid) {
                root = root.rightChild;
            }
        }
        return result;
    }
   
    private void build(Segment root, int left, int right) {
        root.left = left;
        root.right = right;
        if (left != right) {
            int mid = left + (right - left) / 2;
            root.leftChild = new Segment();
            root.rightChild = new Segment();
            build(root.leftChild, left, mid);
            build(root.rightChild, mid + 1, right);
        }
    }
    
    private void insert(Segment root, int left, int right) {
        
        int rootLeft = root.left;
        int rootRight = root.right;
        int rootMid = rootLeft + (rootRight - rootLeft) / 2;
        
        //匹配,出现次数加1
        if (left == rootLeft && right == rootRight) {
            root.count++;
            return;
        }
        
        if (right <= rootMid) {
            insert(root.leftChild, left, right);
        } else if (left > rootMid){
            insert(root.rightChild, left, right);
        } else {
            insert(root.leftChild, left, rootMid);
            insert(root.rightChild, rootMid + 1, right);
        }
    }
    
}

1
2
分享到:
评论

相关推荐

    轻松学习线段树 进来看看

    线段树是一种高效的数据结构,用于处理区间查询和修改操作,特别适用于动态维护区间信息的问题。它的核心思想是将一个区间划分为更小的子区间,并对这些子区间进行分治,从而实现快速的更新和查询。以下是对线段树的...

    权值线段树和主席树入门

    权值线段树和主席树入门PPT,权值线段树,顾名思义就是记录权值的线段树,普通的线段树直接以坐标为l,r建树,而权值线段树是以大小来建树,树上寸的信息是该权值的数量,而通过建树时二分从小到大的性质,可以用这...

    线段树入门讲义(PPT)

    线段树是一种高效的数据结构,主要用于处理区间查询和更新的问题,比如区间加减、求和、最值等。它的核心思想是将一个大区间分解成若干小的子区间,并存储在二叉树的节点中,从而实现对区间操作的快速响应。 线段树...

    线段树入门学习(二)(兼解POJ3468) JAVA

    线段树是一种高效的数据结构,常用于解决区间查询与修改的问题。在本教程中,我们将深入探讨线段树的基本概念,以及如何使用Java实现线段树来解决实际问题,如POJ3468题目。 首先,理解线段树的核心在于它的分治...

    线段树入门

    线段树是一种高效的数据结构,用于处理和维护在一维空间中的一系列区间或线段,同时支持动态查询和修改操作。它特别适用于那些需要快速查询区间信息,如求区间和、查找区间内满足条件的元素个数等问题。线段树的核心...

    线段树入门学习(三)懒操作(兼解POJ1823) JAVA

    线段树是一种高效的数据结构,常用于解决区间查询与修改的问题。在本篇博文中,我们将深入探讨线段树的概念,以及如何实现懒惰更新(Lazy Propagation)策略,同时结合POJ1823问题进行实战应用。懒惰更新是优化线段...

    线段树 入门 总结 Interval Tree

    ### 线段树入门级总结 #### 一、初识线段树 ##### 1、线段树的称谓及意义 线段树(Interval Tree),顾名思义,是一种基于区间的特殊数据结构。它能够高效地解决涉及区间查询和修改的问题,尤其适用于动态查询或...

    线段树+入门+总结+Interval+Tree.rar_algorithm_interval tree_ponyj9e_tree

    线段树(Segment Tree)是一种数据结构,常用于处理区间查询和更新问题。它通过将一维数组分段,每一段对应一个节点,构建出一棵树形结构,从而支持高效地处理区间范围内的数据操作。在算法领域,线段树是解决动态...

    线段树和树状数组入门介绍

    线段树和树状数组是两种在ACM(算法竞赛)和编程中广泛使用的高效数据结构,它们主要用于处理数组上的区间查询和修改操作。这里我们将深入理解这两种数据结构的原理和应用。 首先,线段树是一种能够支持动态维护...

    线段树入门学习(兼解HDU1754)

    这篇博客“线段树入门学习(兼解HDU1754)”旨在帮助初学者理解线段树的基本概念,并通过解决HDU1754题目来实践其应用。 线段树的核心思想是将一个区间分解成多个子区间,然后对每个子区间进行预处理,存储区间的信息...

    Lmne.rar_数值算法/人工智能

    7. **实例分析**:文件"XWn线段树-初步学习.doc"可能是对线段树基础概念的介绍,适合初学者入门;"线段树在程序设计中的应用.doc"可能包含线段树在实际问题中的应用案例,如如何用线段树解决竞赛题目;"v79二分法与...

    CSP-J2022入门组二轮补赛试题(山东)

    解题的关键在于正确处理区间交集,可以采用线段树或者并查集等数据结构优化算法效率。 **第二题 宴会 (banquet)** 这个题目设定在唐朝背景,涉及数学和规划问题。题目要求在数轴上的点安排宴会,考虑每个官员的...

    leetcode线段覆盖-Introduction-to-algorithms:算法

    线段覆盖0.成就 1.目录 C_Cpp STL 分治 动态规划 区间DP 哈希表 图论 最小生成树 最短路 奇思妙想 字符串 字符串匹配 常用技巧 并查集 排序 顺序统计量 搜索 BFS 二分搜索 回溯 数据结构 二叉树 树状数组 树(广义的...

    日常CAD快捷键-快速入门

    - **用途**:绘制连续的线段。 - **应用场景**:绘制轮廓线、路径等。 **ML,** *MLINE(多线)* - **用途**:绘制两条或多条平行线。 - **应用场景**:表示双车道的道路或其他需要平行线的地方。 **SPL,** *SPLINE...

    Acm常用算法学习模板-1

    文件包括以下子文件,每个文件里面包括了一定数量的ppt,doc,c++模板代码,希望对算法...8-线段树 9-树状数组 10-字典树 11-二分图 12-网络流 13-高精度 14-几何 15-自动机 16-DP_01背包 16-DP_树状dp 16-贪心 17-数论

    算法竞赛入门经典--训练指南,代码仓库

    算法竞赛入门经典--训练指南,代码仓库,有四个版本的代码仓库。 《算法竞赛入门经典——训练指南》... 增加线段树部分中两个经典问题的完整代码:快速序列操作I和快速序列操作II 2013-02-28 补全所有159道例题的代码

Global site tag (gtag.js) - Google Analytics