凸包构造算法—Graham 扫描法

1. 理论原理推导

核心思想

Graham 扫描法基于以下基本思想:

  • 极角排序:
    选取一个参考点(通常选择 y 坐标最小的点,若存在多个,则选 x 坐标最小的),将其他点按照与该参考点构成的极角进行升序排序。这样排序后的点序列沿参考点方向依次展开,便于后续的凸包构造。

  • 利用栈进行构造:
    从参考点开始,依次将排序后的点加入栈中。每加入一个新点,都检查当前栈顶的两个点与新点形成的转向:

    • 如果转向为左转(或者说逆时针转),说明当前点有可能是凸包的一部分,继续压入栈中;

    • 如果转向为右转(顺时针)或共线,说明栈顶点不满足凸包条件,需要弹出栈顶点。如此反复,直至满足左转条件,再将当前点压入栈中。

几何证明

  • 正确性证明:
    利用“循环不变量”思想,可以证明:

    • 在每一步,栈中保存的点构成部分凸包(即所有点均处于边界的外侧)。

    • 如果出现右转,则说明栈顶点处于内部,不可能在最终凸包上,将其删除。

    由此,通过反复修正转向,最终栈中剩下的点必然构成整个点集的凸包。

  • 关键性质:
    对于任何三个连续的点 P_{i-2}P_{i-1}P_i,如果构成右转,则 P_{i-1}  一定不在凸包边界上;如果总是保持左转,则整个路径是凸的。
    这一性质正是构造凸包的理论依据。


2. 时间复杂度推导

Graham 扫描法主要分为两个阶段:

  1. 极角排序阶段:

    • 对 n 个点按照极角排序,通常采用快速排序或归并排序,其时间复杂度为 O(nlog⁡n)。

  2. 扫描与构造阶段:

    • 利用栈对排序后的点进行扫描,判断每次转向是否为左转或右转。每个点最多入栈一次、出栈一次,故该阶段的时间复杂度为 O(n)。

综合时间复杂度:
主要耗时在排序阶段,故总体时间复杂度为O(nlog⁡n)


3. 算法步骤

步骤 1:选择参考点

  • 在所有点中选择 y 坐标最小的点作为参考点(若 y 坐标相同,则选择 x 坐标最小的点),记为 P_0

步骤 2:极角排序

  • P_0​ 为原点,计算所有其他点与 P_0 之间的极角。

  • 对所有点(除了 P_0)按照极角升序排序。

    • 注意:在极角相同的情况下,通常保留离 P_0 最近的点,或者按距离排序,确保排序结果有利于凸包构造。

步骤 3:初始化栈

  • P_0 以及排序后的前两个点依次压入栈中。

步骤 4:扫描构造凸包

  • 对于排序后的其余每个点 P_i​(从第 3 个点开始):

    1. 检查栈顶的两个点(记为 P_{top}​ 和 P_{next\_to\_top}​)与 P_i​ 构成的转向。

    2. 如果转向为右转(或共线不满足要求),则说明 P_{top} 不在凸包上,从栈中弹出该点。

    3. 重复上述检查,直到栈顶的两个点与 P_i​ 构成左转为止。

    4. P_i​ 压入栈中。

步骤 5:输出结果

  • 当所有点处理完毕后,栈中保存的点按顺序构成整个点集的凸包。


算法总结

  • 理论原理:
    通过选择参考点、极角排序以及利用栈检查转向,保证了每一次只保留凸包边界上的点。利用几何性质证明了只有左转时点才属于凸包,右转时弹出不符合条件的点。

  • 时间复杂度:
    排序阶段 O(nlog⁡n),扫描阶段 O(n) ,整体为 O(nlog⁡n) 。

  • 算法步骤:
    包含选择参考点、极角排序、栈初始化、扫描构造凸包以及输出结果等步骤,流程清晰且易于实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/74069.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何在 Windows 上安装与配置 Tomcat

Apache Tomcat 是一个开源的 Servlet 容器和 Web 服务器,广泛用于 Java Web 应用的开发和部署。它是实现 Java EE(现称 Jakarta EE)规范中的 Servlet 和 JSP 的官方参考实现。在本文中,我们将详细介绍如何在 Windows 系统上安装并…

测试模版15

本篇技术博文摘要 🌟 引言 📘 在这个变幻莫测、快速发展的技术时代,与时俱进是每个IT工程师的必修课。我是盛透侧视攻城狮,一名什么都会一丢丢的网络安全工程师,也是众多技术社区的活跃成员以及多家大厂官方认可人员&a…

拦截、限流,针对场景详细信息(一)

以下是一个基于Java Spring Boot Redis 的完整限流实现案例,针对同一接口前缀(如 /one/ )的IP访问频率控制: 场景:用户不用登录即可访问接口,网站会有被攻击的风险 URL:one/two/three one/…

计算机视觉算法实战——烟雾检测

✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ ​​​ ​​​​​​​​​ ​​ 1. 烟雾检测领域介绍 烟雾检测是计算机视觉在公共安全领域的重要应用,它通过分析视频或图像序…

MySQL-DCL函数

DCL DCL英文全称是Data Control Language(数据控制语言),用来管理数据库用户、控制数据库的访问权限。 管理用户 1). 查询用户 use mysql; select * from user; select * from mysql.user; 查询的结果如下: 其中 Host代表当前用户访问的主机, 如果为localhost, 仅…

linux 服务器创建服务器启动后服务自启动

1、在/etc/systemd/system/下touch一个文件: touch /etc/systemd/system/your_application.service 2、在文件中写入: [Unit] Descriptionmodules-system Aftersyslog.target[Service] Typeforking Userroot Grouproot ExecStart/bin/bash /usr/loca…

端到端语音识别案例

《DeepSeek大模型高性能核心技术与多模态融合开发(人工智能技术丛书)》(王晓华)【摘要 书评 试读】- 京东图书 语音识别这一技术正如其名,是通过精密地解析说话人的语音来识别并准确转写出其所说的内容。它不仅仅是一个简单的转录过程&#…

QT——信号和槽

QT是图形化界面,自然是需要与用户进行交互的,但是该如何实现用户与界面或者程序的交互呢。答案是通过信号和槽。 一,什么是信号和槽? 在Linux操作系统里面,我们知道信号是由硬件或者软件产生,但是在QT里面…

Q:如何保证备份的有效性以及备份频率设置的优化方案?

1、如何保障备份数据的一致性 a) 快照 快照通过捕获数据在某一时刻的完整状态来保障备份一致性。在应用层,快照会暂停业务写入或生成事务一致性检查点(如数据库的全局读视图),确保备份数据不包含未提交的事务;在存…

Linux实用操作及命令

一、各类小技巧(快捷键) 1、强制停止(ctrlc) Linux某些程序的运行,如果想要强制停止它,可以使用快捷键ctrl c 命令输入错误,也可以通过快捷键ctrl c,退出当前输入,重…

压测工具开发(一)——使用Qt Designer构建简单界面

你好,我是安然无虞。 文章目录 项目功能概述构建菜单栏、工具栏1. 菜单栏注意事项2. 工具栏注意事项3. 日志停靠窗口 项目功能概述 开发一款 Qt版本的压测工具, 可以用来做 基于HTTP API接口的 性能测试. 要求做一个 MDI 多功能子窗口的 图形界面程序, 方便公司内…

Ubuntu 22 Linux上部署DeepSeek R1保姆式操作详解(ollama方式)

操作系统:Ubuntu Linux 22.04 一、安装模型运行环境 打开链接https://ollama.com/download/linux 1.安装ollama (1)一条指令即可实现的简易版安装方法(也可称为在线安装) curl -fsSL https://ollama.com/install.s…

MySQL 和 Redis 数据一致性解决方案

MySQL 和 Redis 数据一致性解决方案 MySQL 和 Redis 作为两种不同类型的数据库(关系型 vs 内存型),在配合使用时需要特别注意数据一致性问题。以下是几种常见的解决方案: 1. 缓存更新策略 1.1 Cache Aside Pattern (旁路缓存模式) 读操作&#xff1a…

Java高频面试之集合-20

hello啊,各位观众姥爷们!!!本baby今天来报道了!哈哈哈哈哈嗝🐶 面试官:讲讲 HashSet 的底层实现? HashSet 是 Java 集合框架中用于存储唯一元素的高效数据结构,其底层实…

【MySQL】从零开始:掌握MySQL数据库的核心概念(四)

人们之所以不愿改变,是因为害怕未知。但历史唯一不变的事实,就是一切都会改变。 前言 这是我自己学习mysql数据库的第四篇博客总结。后期我会继续把mysql数据库学习笔记开源至博客上。 上一期笔记是关于mysql数据库的表格约束,没看的同学可以…

Manus:通用智能体的架构革命与产业破局

🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》、《前端求职突破计划》 🍚 蓝桥云课签约作者、…

HTTP协议手写服务器

目录 一、请求的是Web根目录 二、GET方法通过URL传参 三、根据资源类型对应出Content-Type值 四、Http代码 项目完整源代码:Http 周不才/cpp_linux study - 码云 - 开源中国 一、请求的是Web根目录 如果URL中请求的资源是Web根目录,则自动跳转到主…

小蓝和钥匙

错位排序组合数 从28个人里面选14个人分到原来房间的钥匙 C 28 14 另外14个人错位排序 模板 请在此处填写你的解题思路 D14 都是模板记住就好了 无需理解 做题可以看出来是错位排序 或者组合数 然后会写代码就行了 import java.util.Scanner;/*** author zb* date2025/3…

使用飞书API自动化更新共享表格数据

飞书API开发之自动更新共享表格 天马行空需求需求拆解1、网站数据爬取2、飞书API调用2.1 开发流程2.2 创建应用2.3 配置应用2.4 发布应用2.5 修改表格权限2.6 获取tenant_access_token2.7 调用API插入数据 总结 天马行空 之前一直都是更新的爬虫逆向内容,工作中基本…

Python-Django入手

18.1 建立项目 18.1.1 制定规范 - 定义项目目标:明确应用的核心功能 - 创建项目文档:用README.md记录技术栈和开发流程 - 规划目录结构:建议遵循Django官方推荐的项目布局 18.1.2 建立虚拟环境 在命令行执行: python -m ven…