分治法——凸包问题

凸包问题

相关解读

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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 +
                    '}';
        }
    }
}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

绿豆蛙给生活加点甜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值