四叉树空间索引
四元树又称四叉树是一种树状数据结构,在每一个节点上会有四个子区块。四元树常应用于二维空间数据的分析与分类。它将数据区分成为四个象限。
代码:
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]);
}
}
}