PHP实现的堆排序算法详解


Posted in PHP onAugust 17, 2017

本文实例讲述了PHP实现的堆排序算法。分享给大家供大家参考,具体如下:

经验

工作了,面试我工作这家公司时被技术面打击得不行,因为自己的数据结构等基础学得实在太差,虽然原来是想做设计师的说。。。不过看在PHP写得还凑合的份上能来实习了,但还是决心恶补一下基础。 其实自己之前也确实感觉到了基础的重要性,一些比较深的东西都比较底层,不学好根本没法进行。像我之前用PHP做websocket,就牵扯到数据包、数据帧等概念,搞不清楚,连数据都没法处理,还得后来补。所以我准备重新学一下数据结构,算法,网络等基础知识,也在此跟大家提个醒,别像我一样走反了方向,甚至到明白过来就已经晚了。

今天来说一下被问到的堆排序的问题,当时被问到时,连完全二叉树的概念都忘了。不过幸好我还有一点点数据结构基础,看了点资料也有些明白了,所以想用PHP写一下二叉树的堆排序,顺便也复习下二叉树,堆等数据结构。

堆(heap)是计算机科学中一类特殊的数据结构的统称,通常是一个可以被看做一棵树的数组对象

堆{k1,k2,ki,…,kn} (ki <= k2i,ki <= k2i+1)|(ki >= k2i,ki >= k2i+1), (i = 1,2,3,4...n/2)

关于堆:

堆中某个节点的值总是不大于或不小于其父节点的值;
堆总是一棵完全二叉树(下面)。
将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。

完全二叉树

说到堆排序,就不能不提完全二叉树,这些基本概念在网上到处都是,我摘了个最简单的。。

完全二叉树:除最后一层外,每一层上的节点数均达到最大值;在最后一层上只缺少右边的若干结点。

我自己总结认为,正是因为有下面两个特点,

1. 只允许最后一层有空缺结点且空缺在右边,即叶子结点只能在层次最大的两层上出现(存储方式的规则性);
2. 若i>1,tree的双亲为tree[i div 2](其父子结点值的规律性);

才使得其进行排序非常方便。

堆排序

堆排序求升序用大顶堆,求降序用小顶堆。

本例用求降序的小顶堆来解析。

堆排序步骤如下:

1、我们将数据(49、38、65、97、76、13、27、50)建立一个数组$arr;
2、用数组$arr建立一个小顶堆(主要步骤,会在代码注释里解释,下图是用一个数组建立小顶堆的过程);
3、将堆的根(最小的元素)与最后一个叶子交换,并将堆长度减一,跳到第二步;
4、重复2-3步,直到堆中只有一个结点,排序完成。

PHP实现的堆排序算法详解

堆排序的PHP实现

//因为是数组,下标从0开始,所以,下标为n根结点的左子结点为2n+1,右子结点为2n+2;
//初始化值,建立初始堆
$arr=array(49,38,65,97,76,13,27,50);
$arrSize=count($arr);
//将第一次排序抽出来,因为最后一次排序不需要再交换值了。
buildHeap($arr,$arrSize);
for($i=$arrSize-1;$i>0;$i--){
  swap($arr,$i,0);
  $arrSize--;
  buildHeap($arr,$arrSize);
}
//用数组建立最小堆
function buildHeap(&$arr,$arrSize){
  //计算出最开始的下标$index,如图,为数字"97"所在位置,比较每一个子树的父结点和子结点,将最小值存入父结点中
  //从$index处对一个树进行循环比较,形成最小堆
  for($index=intval($arrSize/2)-1; $index>=0; $index--){
    //如果有左节点,将其下标存进最小值$min
    if($index*2+1<$arrSize){
      $min=$index*2+1;
      //如果有右子结点,比较左右结点的大小,如果右子结点更小,将其结点的下标记录进最小值$min
      if($index*2+2<$arrSize){
        if($arr[$index*2+2]<$arr[$min]){
          $min=$index*2+2;
        }
      }
      //将子结点中较小的和父结点比较,若子结点较小,与父结点交换位置,同时更新较小
      if($arr[$min]<$arr[$index]){
        swap($arr,$min,$index);
      }
    }
  }
}
//此函数用来交换下数组$arr中下标为$one和$another的数据
function swap(&$arr,$one,$another){
  $tmp=$arr[$one];
  $arr[$one]=$arr[$another];
  $arr[$another]=$tmp;
}

下面是排序的最终结果:

PHP实现的堆排序算法详解

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
PHP反转字符串函数strrev()函数的用法
Feb 04 PHP
php错误、异常处理机制(补充)
May 07 PHP
深入解读php中关于抽象(abstract)类和抽象方法的问题分析
Jan 03 PHP
PHPMailer的主要功能特点和简单使用说明
Feb 17 PHP
Php中使用Select 查询语句的实例
Feb 19 PHP
windows7下php开发环境搭建图文教程
Jan 06 PHP
在PHP程序中使用Rust扩展的方法
Jul 03 PHP
WampServer搭建php环境时遇到的问题汇总
Jul 23 PHP
php实现统计目录文件大小的函数
Dec 25 PHP
深入理解PHP中的empty和isset函数
May 26 PHP
php 如何禁用eval() 函数实例详解
Dec 01 PHP
PHP迭代与递归实现无限级分类
Aug 28 PHP
基于php编程规范(详解)
Aug 17 #PHP
PHP数据库操作四:mongodb用法分析
Aug 16 #PHP
PHP Laravel 上传图片、文件等类封装
Aug 16 #PHP
PHP数据库操作三:redis用法分析
Aug 16 #PHP
PHP数据库操作二:memcache用法分析
Aug 16 #PHP
PHP数据库编程之MySQL优化策略概述
Aug 16 #PHP
PHP回调函数与匿名函数实例详解
Aug 16 #PHP
You might like
PHP 中的类
2006/10/09 PHP
php实现的SESSION类
2014/12/02 PHP
php输出金字塔的2种实现方法
2014/12/16 PHP
php curl登陆qq后获取用户信息时证书错误
2015/02/03 PHP
php自定义扩展名获取函数示例
2016/12/12 PHP
PHP实现chrome表单请求数据转换为接口使用的json数据
2021/03/04 PHP
Prototype使用指南之base.js
2007/01/10 Javascript
Js放到HTML文件中的哪个位置有什么区别
2013/08/21 Javascript
AngularJS基础 ng-init 指令简单示例
2016/08/02 Javascript
jQuery实现简洁的轮播图效果实例
2016/09/07 Javascript
canvas绘制表盘时钟
2017/01/23 Javascript
浅谈struts1 &amp; jquery form 文件异步上传
2017/05/25 jQuery
vue语法之拼接字符串的示例代码
2017/10/25 Javascript
详解VUE-地区选择器(V-Distpicker)组件使用心得
2018/05/07 Javascript
Vue.set() this.$set()引发的视图更新思考及注意事项
2018/08/30 Javascript
11个教程中不常被提及的JavaScript小技巧(推荐)
2019/04/17 Javascript
JointJS JavaScript流程图绘制框架解析
2019/08/15 Javascript
总结用Pdb库调试Python的方式及常用的命令
2016/08/18 Python
python中os模块详解
2016/10/14 Python
python利用正则表达式提取字符串
2016/12/08 Python
python爬虫获取京东手机图片的图文教程
2017/12/29 Python
详解Python中的format格式化函数的使用方法
2019/11/20 Python
python json 递归打印所有json子节点信息的例子
2020/02/27 Python
Java ExcutorService优雅关闭方式解析
2020/05/30 Python
踩坑:pytorch中eval模式下结果远差于train模式介绍
2020/06/23 Python
总结Pyinstaller的坑及终极解决方法(小结)
2020/09/21 Python
HTML5拍照和摄像机功能实战详解
2019/01/24 HTML / CSS
应用服务器有那些
2012/01/19 面试题
电脑销售顾问自荐信
2014/01/29 职场文书
中学生旷课检讨书500字
2014/10/29 职场文书
高考作弊检讨书1500字
2015/02/16 职场文书
监理中标通知书
2015/04/16 职场文书
2016学雷锋优秀志愿者事迹材料
2016/02/25 职场文书
JS一分钟在github+Jekyll的博客中添加访问量功能的实现
2021/04/03 Javascript
Python实现Hash算法
2022/03/18 Python
Vue 打包后相对路径的引用问题
2022/06/05 Vue.js