php实现堆排序
时间:2019-03-19
本文章向大家介绍php实现堆排序,主要包括php实现堆排序使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
- <?php
- $arr = [4,1,3,2,16,9,10,1,14,9,8,7,];//注意有重复值。
- $arr = heap_sort($arr);
- var_dump($arr);
- //排序结果如下:
- // [1,1,2,3,4,7,8,9,9,10,14,16,]
- /**
- * 从小到大 的排序。
- *
- * 1、初始化最大堆,把一维数组改变成映射为最大堆的一维数组。
- * 2、把堆顶的最大值和堆最后一个结点交换。(于是最大值出现,并放好位置了。)
- * 3、排除最后一个结点,把堆重新调整为最大堆。
- * 4、把堆顶和倒数第2个结点交换。(于是次大值出现,也放好位置了。)
- * 5、排除最后两个结点,把堆调整为最大推。
- * 6、重复2和3,直到最后一个结点即堆顶。堆顶不需排,因为必然最小。
- *
- * @param array $arr
- * @return array
- */
- function heap_sort($arr) {
- $len = count($arr);
- //初始化,i從最後一個父節點開始調整
- // 初始化的目的是建立一个最大堆。
- // 要点是,必须自底向上,而不能自顶向下,否则bug。
- for ($index = ceil($len/2) - 1; $index >= 0; $index--) {
- max_heapify($arr, $index, $len);
- }
- // 推排序是很有规律的,先找出最大值,放到堆的最后,然后假装堆的结点数减少,
- // 继续排序,找出次大的,等等。
- // 巧妙利用堆和数组的映射,实现排序。
- for ($index = $len - 1; $index > 0; $index--) {
- $arr = swap ( $arr, 0, $index );
- max_heapify($arr, 0, $index);
- }
- return $arr;
- }
- /**
- * 堆排序核心算法,
- * 对于一个给定的堆,给定的起始下标和结束下标,进行堆排序,会递归调用。
- * 事实上,只排序起始下标指向的父节点,结束下标仅仅用于递归判断的返回。
- * 这是指针形式的调用,这样的话,代码速度快,且代码容易理解。
- *
- * @param array $arr
- * @param int $start_index
- * @param int $end_index
- */
- function max_heapify(&$arr, $start_index, $end_index) {
- //建立父節點指標和子節點指標
- $dad_index = $start_index;
- $son_index = $dad_index * 2 + 1;
- //若子節點指標超過範圍直接跳出函數
- if ($son_index >= $end_index) {
- return;
- }
- //先比較兩個子節點大小,選擇最大的
- if ($son_index + 1 < $end_index && $arr[$son_index] < $arr[$son_index + 1]) {
- $son_index++;
- }
- //如果父節點小於子節點時,交換父子內容再繼續子節點和孫節點比較
- if ($arr[$dad_index] < $arr[$son_index]) {
- $arr = swap($arr, $dad_index, $son_index);
- max_heapify($arr, $son_index, $end_index);
- }
- }
- /**
- * 交换一个数组中两个不同下标的值。
- * @param array $arr
- * @param int $index1
- * @param int $index2
- * @return array
- */
- function swap($arr, $index1, $index2) {
- list( $arr[$index1], $arr[$index2] ) = [ $arr[$index2], $arr[$index1] ];
- return $arr;
- }
其实可以看到,堆排序代码并不算多,关键在于理解。
本文有参考:http://bubkoo.com/2014/01/14/sort-algorithm/heap-sort/
作者不知是谁,描述的很清楚。
- 堆是一棵二叉数。
- 堆是一棵完全二叉数,于是,堆可以轻松用数组表达
- 假设下标是i,则父节点和子节点都有下标计算公式。
- 堆排序算法是先初始化成最大堆,然后交换堆顶和堆最后结点,然后结点数减1,再依次操作,就排序好了。
下图仅供参考,注意开始已经初始化过最大堆了。
- php概述
- php教程
- php环境搭建
- PHP书写格式
- php变量
- php常量
- PHP注释
- php数组
- php字符串 string
- PHP整型 integer
- PHP浮点型 float
- php布尔型
- php数据类型之数组
- php数据类型之对象
- php数据类型之null
- php数据类型之间的转换
- php运算符
- php表达式
- PHP循环控制
- PHP流程控制
- php函数
- php全局变量
- PHP魔术变量
- php命名空间
- php 日期
- PHP包含文件
- php文件
- PHP 文件上传
- php Cookies
- php Sessions
- php email
- php安全email
- php错误处理
- PHP异常处理
- php过滤器
- PHP 高级过滤器
- php json
- php 表单
- PHP MySQL 简介
- PHP 连接 MySQL
- php创建数据库
- php 创建表
- php mysq 插入数据
- PHP MySQL 插入多条数据
- PHP MySQL 预处理语句
- php mysql 读取数据
- php mysql where
- PHP MySQL Order By
- PHP MySQL Update
- PHP MySQL Delete
- php ODBC
- SSH端口转发
- 文本处理三剑客之—awk
- Python办公自动化|批量提取Excel数据
- 3分钟短文 | 有挑战!PHP用1个函数实现post请求,你用哪个?
- linux 磁盘管理
- linux 安装各个版本nodejs
- python3 使用cookie模拟post实现修改活码内容
- VIM 创建程序文件自动添加头部注释
- 【简记】Linux 计划任务 Crontab
- VS Code 免密登录Linux服务器
- Linux部署私钥实现免密登录
- 搭建Jenkins+tomcat+maven+Gitlab持续部署/回滚系统
- Java--注解
- 如何在 Ubuntu 20.04 上安装 Jenkins
- 在 Linux 下如何检查内存使用率