php堆排序实现原理与应用方法


Posted in PHP onJanuary 03, 2015

本文实例讲述了php堆排序实现原理与应用方法。分享给大家供大家参考。具体分析如下:

这里以php作为描述语言较详细讲解堆排序原理,因保证程序可读性,故不做优化,php程序中关于堆的一些概念如下:

假设n为当前数组的key则,n的父节点为 n>>1 或者 n/2(整除);n的左子节点l= n<<1 或 l=n*2,n的右子节点r=(n<<1)+1 或 r=l+1

$arr=array(1,8,7,2,3,4,6,5,9);

数组$arr的原形态结构如下:

             1
           /   
         8      7
       /         /
     2     3      4  6
    /
   5  9
heapsort($arr);print_r($arr);

排序后生成标准的小顶堆结构如下:

             1
           /  
         2      3
       /       / 
     4    5      6   7
    /
   8  9
既数组:array(1,2,3,4,5,6,7,8,9):

function heapsort(&$arr) 

{ 

        //求最后一个元素位 

        $last=count($arr); 

        //堆排序中通常忽略$arr[0] 

        array_unshift($arr,0); 

        //最后一个非叶子节点 

        $i=$last>>1; 

 

        //整理成大顶堆,最大的数整到堆顶,并将最大数和堆尾交换,并在之后的计算中忽略数组后端的最大数(last),直到堆顶(last=堆顶) 

        while(true) 

        { 

                adjustnode($i,$last,$arr); 

                if($i>1) 

                { 

                        //移动节点指针,遍历所有非叶子节点 

                        $i--; 

                } 

                else 

                { 

                        //临界点last=1,既所有排序完成 

                        if($last==1)break; 

                        //当i为1时表示每一次的堆整理都将得到最大数(堆顶,$arr[1]),重复在根节点调整堆 

                        swap($arr[$last],$arr[1]); 

                        //在数组尾部按大小顺序保留最大数,定义临界点last,以免整理堆时重新打乱数组后面已排序好的元素 

                        $last--; 

                } 

        } 

        //弹出第一个数组元素 

        array_shift($arr); 

} 

 

//整理当前树节点($n),临界点$last之后为已排序好的元素 

function adjustnode($n,$last,&$arr) 

{ 

        $l=$n<<1;        //$n的左孩子位 

        if(!isset($arr[$l])||$l>$last) return ; 

        $r=$l+1;        //$n的右孩子位 

 

        //如果右孩子比左孩子大,则让父节点的右孩子比 

        if($r<=$last&&$arr[$r]>$arr[$l]) $l=$r; 

        //如果其中子节点$l比父节点$n大,则与父节点$n交换 

        if($arr[$l]>$arr[$n])                 

        { 

                //子节点($l)的值与父节点($n)的值交换 

                swap($arr[$l],$arr[$n]); 

                //交换后父节点($n)的值($arr[$n])可能还小于原子节点($l)的子节点的值,所以还需对原子节点($l)的子节点进行调整,用递归实现 

                adjustnode($l,$last,$arr); 

        }

} 

 

//交换两个值 

function swap(&$a,&$b) 

{ 

        $a=$a ^ $b;

         $b=$a ^ $b;

         $a=$a ^ $b; 

}

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

PHP 相关文章推荐
PHP中通过ADO调用Access数据库的方法测试不通过
Dec 31 PHP
PHP文件打开、关闭、写入的判断与执行代码
May 24 PHP
PHP eval函数使用介绍
Dec 08 PHP
zf框架的db类select查询器join链表使用示例(zend框架)
Mar 14 PHP
php通过strpos查找字符串出现位置的方法
Mar 17 PHP
浅谈php中include文件变量作用域
Jun 18 PHP
php自定义类fsocket模拟post或get请求的方法
Jul 31 PHP
PHP中的use关键字及文件的加载详解
Nov 28 PHP
highchart数据源纵轴json内的值必须是int(详解)
Feb 20 PHP
php 7新特性之类型申明详解
Jun 06 PHP
PHP基于双向链表与排序操作实现的会员排名功能示例
Dec 26 PHP
php字符串过滤strip_tags()函数用法实例分析
Jun 24 PHP
php购物车实现方法
Jan 03 #PHP
PHP实现格式化文件数据大小显示的方法
Jan 03 #PHP
php自定义加密与解密程序实例
Dec 31 #PHP
推荐一本PHP程序猿都应该拜读的书
Dec 31 #PHP
推荐10个提供免费PHP脚本下载的网站
Dec 31 #PHP
php使用google地图应用实例
Dec 31 #PHP
php将文本文件转换csv输出的方法
Dec 31 #PHP
You might like
解析smarty 截取字符串函数 truncate的用法介绍
2013/06/20 PHP
php禁用函数设置及查看方法详解
2016/07/25 PHP
phpinfo()中Loaded Configuration File(none)的解决方法
2017/01/16 PHP
用jquery实现学校的校历(asp.net+jquery ui 1.72)
2010/01/01 Javascript
Firefox/Chrome/Safari的中可直接使用$/$$函数进行调试
2012/02/13 Javascript
Jquery中children与find之间的区别详细解析
2013/11/29 Javascript
js删除局部变量的实现方法
2016/06/25 Javascript
jQuery基于BootStrap样式实现无限极地区联动
2016/08/26 Javascript
JQuery PHP图片在线裁剪实例
2020/07/27 Javascript
jQuery checkbox选中问题之prop与attr注意点分析
2016/11/15 Javascript
js仿微信公众平台打标签功能
2017/04/08 Javascript
socket.io学习教程之基础介绍(一)
2017/04/29 Javascript
nodejs后台集成ueditor富文本编辑器的实例
2017/07/11 NodeJs
jQuery选择器之基本选择器用法实例分析
2019/02/19 jQuery
Vue在 Nuxt.js 中重定向 404 页面的方法
2019/04/23 Javascript
[03:01]DOTA2英雄基础教程 露娜
2014/01/07 DOTA
[05:10]2014DOTA2国际邀请赛 通往胜利之匙赛场探秘之旅
2014/07/18 DOTA
python list排序的两种方法及实例讲解
2017/03/20 Python
Python 变量的创建过程详解
2019/09/02 Python
Django静态文件加载失败解决方案
2020/08/26 Python
python爬虫看看虎牙女主播中谁最“顶”步骤详解
2020/12/01 Python
Pycharm创建python文件自动添加日期作者等信息(步骤详解)
2021/02/03 Python
关于HTML5 Placeholder新标签低版本浏览器下不兼容的问题分析及解决办法
2016/01/27 HTML / CSS
享誉全球的多元化时尚精品购物平台:Farfetch发发奇(支持中文)
2017/08/08 全球购物
荷兰网上买鞋:MooieSchoenen.nl
2017/09/12 全球购物
精伦电子Java笔试题
2013/01/16 面试题
将n个数按输入顺序的逆序排列,用函数实现
2012/11/14 面试题
社区领导班子四风问题原因分析及整改措施
2014/09/28 职场文书
群众路线领导班子整改方案
2014/10/25 职场文书
电信营业员岗位职责
2015/04/14 职场文书
开会迟到检讨书范文
2015/05/06 职场文书
电影地道战观后感
2015/06/04 职场文书
法人身份证明书
2015/06/18 职场文书
信用卡工作证明范本
2015/06/19 职场文书
幽默导游词应该怎么写?
2019/08/26 职场文书
Java org.w3c.dom.Document 类方法引用报错
2021/08/07 Java/Android