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 相关文章推荐
discuz Passport 通行证 整合笔记
Jun 30 PHP
php $_ENV为空的原因分析
Jun 01 PHP
PHP设计模式之迭代器模式的深入解析
Jun 13 PHP
php实现aes加密类分享
Feb 16 PHP
php实现四舍五入的方法小结
Mar 03 PHP
php开发中的页面跳转方法总结
Apr 26 PHP
php使用pclzip类实现文件压缩的方法(附pclzip类下载地址)
Apr 30 PHP
ThinkPHP5实现作业管理系统中处理学生未交作业与已交作业信息的方法
Nov 12 PHP
PHP实现对xml的增删改查操作案例分析
May 19 PHP
thinkphp5使html5实现动态跳转的例子
Oct 16 PHP
PHP使用JpGraph绘制折线图操作示例【附源码下载】
Oct 18 PHP
使用Rancher在K8S上部署高性能PHP应用程序的教程
Jul 10 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中json_encode中文编码问题分析
2011/09/13 PHP
php单例模式实现(对象只被创建一次)
2012/12/05 PHP
smarty模板引擎从配置文件中获取数据的方法
2015/01/22 PHP
thinkphp多层MVC用法分析
2015/12/30 PHP
Laravel 5.3 学习笔记之 配置
2016/08/28 PHP
jquery通过visible来判断标签是否显示或隐藏
2014/05/08 Javascript
利用jquery操作Radio方法小结
2014/10/20 Javascript
jquery的总体架构分析及实现示例详解
2014/11/08 Javascript
JS实现淡蓝色简洁竖向Tab点击切换效果
2015/10/06 Javascript
AngularJS中的表单简单入门
2016/07/28 Javascript
使用nodejs中httpProxy代理时候出现404异常的解决方法
2016/08/15 NodeJs
javascript中href和replace的比较(详解)
2016/11/25 Javascript
Vue.js基础指令实例讲解(各种数据绑定、表单渲染大总结)
2017/07/03 Javascript
简单谈谈React中的路由系统
2017/07/25 Javascript
jQuery Datatable 多个查询条件自定义提交事件(推荐)
2017/08/24 jQuery
聊聊那些使用前端Javascript实现的机器学习类库
2017/09/18 Javascript
浅谈Koa服务限流方法实践
2017/10/23 Javascript
javascript中call()、apply()的区别
2019/03/21 Javascript
谈谈IntersectionObserver懒加载的具体使用
2019/10/15 Javascript
js中switch语句的学习笔记
2020/03/25 Javascript
[04:36]DOTA2国际邀请赛 ti3精彩集锦
2013/08/19 DOTA
python 根据pid杀死相应进程的方法
2017/01/16 Python
Python单例模式的两种实现方法
2017/08/14 Python
对Python3 序列解包详解
2019/02/16 Python
python模拟键盘输入 切换键盘布局过程解析
2019/08/15 Python
python实现单链表的方法示例
2019/09/03 Python
新年福利来一波之Python轻松集齐五福(demo)
2020/01/20 Python
浅谈keras中的Merge层(实现层的相加、相减、相乘实例)
2020/05/23 Python
python制作微博图片爬取工具
2021/01/16 Python
PyQt5通过信号实现MVC的示例
2021/02/06 Python
会话Bean的种类
2013/11/07 面试题
linux面试相关问题
2013/04/28 面试题
大四毕业生学习总结的自我评价
2013/10/31 职场文书
学校关爱留守儿童活动方案
2014/08/27 职场文书
幼儿园辞职信
2015/05/13 职场文书
php实例化对象的实例方法
2021/11/17 PHP