2020-11-17

四叉树空间索引

四元树又称四叉树是一种树状数据结构,在每一个节点上会有四个子区块。四元树常应用于二维空间数据的分析与分类。它将数据区分成为四个象限。

代码:

package text;
import java.util.*;

class TreeNode{
	List<Integer> node;
	int size;
	int lx;
	int ly;
	int rx;
	int ry;
	TreeNode first;
	TreeNode second;
	TreeNode third;
	TreeNode fourth;
	
	TreeNode(){}
	TreeNode(List<Integer> list,int lx,int ly,int rx,int ry){
		node = new LinkedList<Integer>(list);
		size = node.size();
		this.lx = lx;
		this.ly = ly;
		this.rx = rx;
		this.ry = ry;
	}
}

public class Solutionplus {
	public static TreeNode createTree(int[][] posList) {
		if(posList == null || posList.length == 0) return null;
		List<Integer> lis = new LinkedList<>();
		for(int i=0;i<posList.length;i++) {
			lis.add(i);
		}
		
		int lx = posList[0][0],ly = posList[0][1],rx = posList[0][0],ry = posList[0][1];
		
		for(int i:lis) {
			lx = Math.min(lx, posList[i][0]);
			ly = Math.min(lx, posList[i][1]);
			rx = Math.max(lx, posList[i][0]);
			ry = Math.max(lx, posList[i][1]);
		}
		TreeNode root = createTreeCore(posList,lis,lx,ly,rx,ry);
		
		return root;
	}
	public static TreeNode createTreeCore(int[][] posList,List<Integer> list,int lx,int ly,int rx,int ry){
		
		int midx = (lx+rx)/2;
		int midy = (ly+ry)/2;
		
		List<Integer> firstList = new LinkedList<>();
		List<Integer> secondList = new LinkedList<>();
		List<Integer> thirdList = new LinkedList<>();
		List<Integer> fourthList = new LinkedList<>();
		
		for(int i:list) {
			if(posList[i][0] <= midx) {
				if(posList[i][1] <= midy) {
					firstList.add(i);
				}else {
					secondList.add(i);
				}
			}else {
				if(posList[i][1] <= midy) {
					thirdList.add(i);
				}else {
					fourthList.add(i);
				}
			}
		}
		
		TreeNode root = new TreeNode(list,lx,ly,rx,ry);
		
		if(firstList.size() <= 4&&firstList.size()>0) {
			root.first = new TreeNode(firstList,lx,ly,midx,midy);
		}else if(firstList.size() > 4) {
			root.first = createTreeCore(posList,firstList,lx,ly,midx,midy);
		}
		
		if(secondList.size()<=4&&secondList.size()>0) {
			root.second = new TreeNode(secondList,midx,ly,rx,midy);
		}else if(secondList.size() > 4) {
			root.second = createTreeCore(posList,secondList,midx,ly,rx,midy);
		}
		if(thirdList.size()<=4&&thirdList.size()>0) {
			root.third = new TreeNode(thirdList,lx,midy,midx,ry);
		}else if(thirdList.size() > 4) {
			root.third = createTreeCore(posList,thirdList,lx,midy,midx,ry);
		}
		
		if(fourthList.size()<=4&&thirdList.size()>0) {
			root.fourth = new TreeNode(fourthList,midx,midy,rx,ry);
		}else if(fourthList.size() > 4) {
			root.fourth = createTreeCore(posList,fourthList,midx,midy,rx,ry);
		}
		
		return root;
	}
	
	public static List<Integer> count(TreeNode root,int x,int y,int n,int[][] posList) {
		if(root == null) return null;
		int lx = x-(n/2);
		int ly = y-(n/2);
		int rx = x+(n/2);
		int ry = y+(n/2);
		
		List<Integer> ans = new LinkedList<>();
		countCore(root,lx,ly,rx,ry,ans,posList);
		return ans;
		
	}
	
	public static void countCore(TreeNode root,int lx,int ly,int rx,int ry,List<Integer> ans,int[][] posList) {
		if(root == null) return ;
		
		if(lx<=root.lx&&ly<=root.ly&&rx>=root.rx&&ry>=root.ry) {
			ans.addAll(root.node);
		}else {
			if(check(lx,ly,rx,ry,root.lx,root.ly)||check(lx,ly,rx,ry,root.lx,root.ry)||check(lx,ly,rx,ry,root.rx,root.ly)||check(lx,ly,rx,ry,root.rx,root.ry)) {
				if(root.first == null&&root.second == null&&root.third == null&&root.fourth == null) {
					for(int i:root.node) {
						if(posList[i][0]<=rx&&posList[i][0]>=lx&&posList[i][1]<=ry&&posList[i][1]>=ly) {
							ans.add(i);
						}
					}
				}else {
					countCore(root.first,lx,ly,rx,ry,ans,posList);
					countCore(root.second,lx,ly,rx,ry,ans,posList);
					countCore(root.third,lx,ly,rx,ry,ans,posList);
					countCore(root.fourth,lx,ly,rx,ry,ans,posList);
				}
			}
			
		}
		
		
	}
	
	public static boolean check(int lx,int ly,int rx,int ry,int targetx,int targety) {
		if(targetx<=rx&&targetx>=lx&&targety<=ry&&targety>=ly) {
			return true;
		}
		return false;
	}
	
	public static void main(String[] args) {
		int[][] pos = {{0,0},{1,1},{2,2},{2,3},{3,3},{1,2},{3,1},{5,4},{5,5}};
		TreeNode root = createTree(pos);
		List<Integer> list = count(root,1,1,2,pos);
		for(int i:list) {
			System.out.println(pos[i][0]+ "  " + pos[i][1]);
		}
		
		
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值