线段树的创建

  • Post author:
  • Post category:其他



线段树的创建


代码是以求和为例


private void buildSegmentTree(int treeIndex,int l,int r);


treeIndex 是当前的位置,就是从头部,


l是左边界,r是右边界


buildSegmentTree(0,0,data.length-1);


mid求中间的位置 吧线段树分为两个部分 左边和右边


左边的开始边界就是l,最后边界就是mid


右边的边界开始是mid+1,末尾就是r


int mid=l+(r-l)/2;// (l+r)/2可以这样写,但是为了防止溢出l+(r-l)/2


左边一直递归,右边一样


buildSegmentTree(leftTreeIndex, l, mid);//左边节点

buildSegmentTree(rightTreeIndex, mid+1, r);//右边节点



最后是相加,因为不能扩展相加,自己定义了融合方法 merger

tree[treeIndex]=merger.merge(data[leftTreeIndex],data[r]);

        //在treeIndex的位置创建表示区间[l...r]的线段树
	private void buildSegmentTree(int treeIndex,int l,int r){
		
		if(l==r){//相等 一个位置就是左边或者最后一个
			tree[treeIndex]=data[l];
			return ;
		}
		
		int leftTreeIndex=leftChild(treeIndex);//左边节点
		int rightTreeIndex=rightChild(treeIndex);//右节点
		
		int mid=l+(r-l)/2;// (l+r)/2可以这样写,但是为了防止溢出l+(r-l)/2
		buildSegmentTree(leftTreeIndex, l, mid);//左边节点
		buildSegmentTree(rightTreeIndex, mid+1, r);//右边节点
		
		
		tree[treeIndex]=merger.merge(data[leftTreeIndex],data[r]);
	}


融合的代码

package com.binglian.SegmentTree;

/**
 * 融合器,两个相加
 * @author binglian
 *
 */
public interface Merger<E> {
	
	E merge(E a,E b);

	
}


主方法这里用到了jdk8的特性


吧匿名函数改为了拉姆达表达式(简化了函数)

package com.binglian.SegmentTree;

public class Main {

	public static void main(String[] args) {

		Integer[] nums={-2,0,3,-5,2,-1};
//		SegmentTree<Integer> segmentTree=new SegmentTree<Integer>(nums,new Merger<Integer>() {
//			
//			public Integer merge(Integer a,Integer b){
//				return a+b;
//			}
//		});
		
		//上面的匿名函数可以表示如下的简便方法
		SegmentTree<Integer> segmentTree=new SegmentTree<Integer>(nums,(a,b)->a+b);
		System.out.println(segmentTree);
	}

}



版权声明:本文为xiaoxin0630原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。