segment tree

 

 

数组实现方式(类似与heap的实现方式):

class NumArray {
    int[] arr=null;
    int len = 0;
    public NumArray(int[] nums) {
        len = nums.length;
        arr = new int[len*10];
        buildSegTree(nums,0,len-1,arr,0);
    }
    public void buildSegTree( int[] nums,int start,int end,int[] arr,int idx ){
        if(start==end){
            arr[idx] = nums[start];
            return;
        }
        
        int mid = start+(end-start)/2;
        int left = idx*2+1;
        buildSegTree(nums,start,mid,arr,left);
        int right = idx*2+2;
        buildSegTree(nums,mid+1,end,arr,right);
        
        arr[idx] = arr[left]+arr[right];
        // printTree();
    }
    public void update(int index, int val) {
         // printTree();
        updateSegTree(0,len-1,arr,0,index,val);
         // printTree();        
    }
    public void updateSegTree(int start,int end,int[] arr,int arrIdx,int index,int val){
        if(index<start || index>end) return;
        if(start==end) arr[arrIdx]=val;
        else{
            int mid = start+(end-start)/2;
            int left = arrIdx*2+1;
            updateSegTree(start,mid,arr,left,index,val);
            int right = arrIdx*2+2;
            updateSegTree(mid+1,end,arr,right,index,val);
            arr[arrIdx] = arr[left]+arr[right];
        }
    }
    
    public int sumRange(int left, int right) {
        return sumSegTree(left,right,arr,0,len-1,0);
    }
    /**
    * l: 原始数组左边界
      r: 原始数组右边界
      arr: sum数组
      start: 原始数组开始
      end:  原始数组结束
      idx:  当前节点
    */
    public int sumSegTree(int l,int r,int[] arr,int start,int end,int idx){
        if(l>end || r<start) return 0;
        if(start==end) return arr[idx];
        if( l<=start && end<=r ) return arr[idx];
        int mid = start+(end-start)/2;
        return sumSegTree(l,r,arr,start,mid,idx*2+1) + sumSegTree(l,r,arr,mid+1,end,idx*2+2);
    }
    public void printTree(){
        for(int num:arr)
            System.out.print(num+" ");
        System.out.println();
    }
}

/**
 * Your NumArray object will be instantiated and called as such:
 * NumArray obj = new NumArray(nums);
 * obj.update(index,val);
 * int param_2 = obj.sumRange(left,right);
 */

 TreeNode 实现方式(类似二叉树实现方式)

class NumArray {
    //定义SegmentTree 节点数据结构
    class SegNode{
        SegNode left;
        SegNode right;
        int sum;
        SegNode(SegNode left,SegNode right,int sum){
            this.left = left;
            this.right = right;
            this.sum = sum;
        }
    }
    private SegNode root = null;
    private int len;
    public NumArray(int[] nums) {
        len = nums.length;
        root = buildSegTree(nums,0,len-1);
    }
    
    public SegNode buildSegTree(int[] nums,int start,int end){
        if(start==end) return new SegNode(null,null,nums[start]);
        int mid = (start+end)/2;
        SegNode left = buildSegTree(nums,start,mid);
        SegNode right = buildSegTree(nums,mid+1,end);
        return new SegNode(left,right,left.sum+right.sum);
    }
    
    public void update(int index, int val) {
        updateSegNode(root,0,len-1,index,val);
    }
    public void updateSegNode(SegNode root,int start,int end,int index,int val){
        if(start>index||end<index) return ;
        if(start==end){
            root.sum = val;
            return;
        }
        int mid = (start+end)/2;
        updateSegNode(root.left, start,mid,index,val);
        updateSegNode(root.right,mid+1,end,index,val);
        root.sum = root.left.sum+root.right.sum;
    }
    
    public int sumRange(int left, int right) {
        return getSegSum(root,0,len-1,left,right);
    }
    public int getSegSum(SegNode root,int start,int end,int left,int right){
        if(start>right || end<left) return 0;
        if(start==end) return root.sum;
        if(left<start && end<right) return root.sum;
        int mid = (start+end)/2;
        return getSegSum(root.left, start,mid,left,right)
            +  getSegSum(root.right,mid+1,end,left,right);
    }
}

/**
 * Your NumArray object will be instantiated and called as such:
 * NumArray obj = new NumArray(nums);
 * obj.update(index,val);
 * int param_2 = obj.sumRange(left,right);
 */

 

posted @ 2021-09-12 23:31  xiaoyongyong  阅读(64)  评论(0)    收藏  举报