java 数据结构源码--线段树

线段树模板


package segmentTree;

public 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);  
        }  
    }  
	

}

测试源码 test.java


/** 
 * 线段树入门 
 * 问题:已知线段[2,5] [4,6] [0,7];求点2,4,7分别出现了多少次 
 * 以下代码建立的线段树用链表来保存,且树的叶子结点类似[i,i] 
 */  


package segmentTree;
import segmentTree.SegmentTree;

public class test {
	
	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));  
        }  
    }  
	

}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值