php 堆排序
2015-10-19 15:30
495 查看
<?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(11,88,7,2,3,24,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之后为已排序好的元素 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; }
以前收藏的代码分析、备忘。
相关文章推荐
- 一个关于if else容易迷惑的问题
- PHP5.2.*防止Hash冲突拒绝服务攻击的Patch
- 深入理解PHP之匿名函数
- JSP/PHP基于Ajax的分页功能实现
- 堆排序
- 关于PHP通过PDO用中文条件查询MySQL的问题。
- 什么是设计模式
- PHP数据库长连接mysql_pconnect的细节
- Php Installing An Expansion
- PHP+Apache在Windows 9x下的安装和配置
- IIS 6 的 PHP 最佳配置方法
- 安装Apache和PHP的一些补充
- Linux Apache+MySQL+PHP
- 建立Apache+PHP+MySQL数据库驱动的动态网站
- PHP 5.3.0 安装分析心得
- apache 环境下 php 的配置注意事项
- C#堆排序实现方法
- ASP.NET、ASP、PHP、JSP之间有什么区别?
- PHP VBS JS 函数 对照表