分治法——凸包问题
凸包问题
相关解读
Java代码
package com.算法.分治法;import java.util.*;/ * @Author Lanh /public class 凸包问题 { public static void main(String[] args) { int[][] matrix = {{12,5},{23,1},{3,27},{65,4},{2,5},{5,3},{3,7},{5,7}}; List<Node> P = new ArrayList<>(); for (int[] ints : matrix) P.add(new Node(ints[0], ints[1],0)); Set<Node> result = ConvexHull(P); System.out.println(result); } public static Set<Node> ConvexHull(List<Node> P){ if (P.size()<=2) new HashSet<>(P); Set<Node> result = new HashSet<>(); P.sort(Comparator.comparingInt(o -> o.x)); Node n1 = P.get(0); Node n2 = P.get(P.size()-1); result.add(n1); result.add(n2); List<Node> u = new ArrayList<>(); List<Node> d = new ArrayList<>(); for (int i=1;i<P.size()-1;i++){ Node p = P.get(i); int prod = sign(n1,n2,p); if (prod>0) u.add(p); else if (prod<0) d.add(p); p.prod = prod; } result.addAll(upConvexHull(u,n1,n2)); result.addAll(downConvexHull(d,n1,n2)); return result; } private static Set<Node> downConvexHull(List<Node> list, Node n1, Node n2) { if (list.size()<=1) return new HashSet<>(list); else { Set<Node> result = new HashSet<>(); //大家的底都是n1n2,所以直接比较面积大小即可 Node max = list.get(0); for (Node node:list){ if (Math.abs(max.prod)<Math.abs(node.prod)) max = node; } List<Node> d1 = new ArrayList<>(); List<Node> d2 = new ArrayList<>(); result.add(max); for (Node node:list){ int prod = sign(n1,max,node); if (prod<0) { d1.add(node); }else { prod = sign(max,n2,node); if (prod<0) d2.add(node); } node.prod = prod; } result.addAll(upConvexHull(d1,n1,max)); result.addAll(upConvexHull(d2,max,n2)); return result; } } private static Set<Node> upConvexHull(List<Node> list, Node n1, Node n2) { if (list.size()<=1) return new HashSet<>(list); else { Set<Node> result = new HashSet<>(); //大家的底都是n1n2,所以直接比较面积大小即可 Node max = list.get(0); for (Node node:list){ if (max.prod<node.prod) max = node; } List<Node> u1 = new ArrayList<>(); List<Node> u2 = new ArrayList<>(); result.add(max); for (Node node:list){ int prod = sign(n1,max,node); if (prod>0) { u1.add(node); }else { prod = sign(max,n2,node); if (prod>0) u2.add(node); } node.prod = prod; } result.addAll(upConvexHull(u1,n1,max)); result.addAll(upConvexHull(u2,max,n2)); return result; } } public static int sign(Node n1,Node n2,Node n3){ return n1.x* n2.y+ n3.x*n1.y+ n2.x* n3.y- n3.x* n2.y- n2.x* n1.y- n1.x* n3.y; } static class Node{ int x;int y;int prod; Node(int x,int y,int prod){ this.x = x; this.y = y; this.prod = prod; } @Override public String toString() { return "Node{" + "x=" + x + ", y=" + y + '}'; } }}