zoukankan      html  css  js  c++  java
  • PHP SPL神器实现堆排序

    之前学习过内部排序的八大算法,也一一写过代码实现。其中堆排序的原理是

    • 将一颗二叉树初始化为堆
    • 依次将最后一个结点与堆顶结点交换。然后调整堆顶元素位置,重置堆。

    将二叉树初始化为堆可以看做从最后一个非叶子结点开始,依次调整子堆的堆顶元素,重置堆是指重置堆顶元素。

    这种算法的实现如下:

    <?php
    #堆排序
    function heapSort(&$arr) {
    	#初始化大顶堆
    	initHeap($arr);
    
    	#开始交换首尾节点,并每次减少一个末尾节点再调整堆,直到剩下一个元素
    	for($end = count($arr) - 1; $end >= 0; $end--) {
    		$temp = $arr[0];
    		$arr[0] = $arr[$end];
    		$arr[$end] = $temp;
    		ajustNodes($arr, 0, $end - 1);
    	}
    }
    
    #初始化最大堆,从最后一个非叶子节点开始,最后一个非叶子节点编号为 数组长度/2 向下取整
    function initHeap(&$arr) {
    	$len = count($arr);
    	for($start = floor($len / 2) - 1; $start > 0; $start--) {
    		ajustNodes($arr, $start, $len - 1);
    	}
    }
    
    #调整节点
    #@param $arr    待调整数组
    #@param $start    调整的父节点坐标
    #@param $end    待调整数组结束节点坐标
    function ajustNodes(&$arr, $start, $end) {
    	$maxInx = $start;
    	$len = $end + 1;    #待调整部分长度
    	$leftChildInx = ($start + 1) * 2 - 1;    #左孩子坐标
    	$rightChildInx = ($start + 1) * 2;    #右孩子坐标
    
    	#如果待调整部分有左孩子
    	if($leftChildInx + 1 <= $len) {
    		#获取最小节点坐标
    		if($arr[$maxInx] < $arr[$leftChildInx]) {
    			$maxInx = $leftChildInx;
    		}
    
    		#如果待调整部分有右子节点
    		if($rightChildInx + 1 <= $len) {
    			if($arr[$maxInx] < $arr[$rightChildInx]) {
    				$maxInx = $rightChildInx;
    			}
    		}
    	}
    
    	#交换父节点和最大节点
    	if($start != $maxInx) {
    		$temp = $arr[$start];
    		$arr[$start] = $arr[$maxInx];
    		$arr[$maxInx] = $temp;
    
    		#如果交换后的子节点还有子节点,继续调整
    		if(($maxInx + 1) * 2 <= $len) {
    			ajustNodes($arr, $maxInx, $end);
    		}
    	}
    }
    
    $arr = array(1, 5, 3, 7, 9 ,10, 2, 8);
    heapSort($arr);
    print_r($arr);
    ?>
    

      现在学了SPL这种神器,看下如何实现堆排序:

    <?php 
    function splHeapSort($arr){
    	$heap = new SplMinHeap();
    	
    	//初始化小顶堆
    	foreach ($arr as $v){
    		$heap->insert($v);
    	}
    	
    	while(!$heap->isEmpty()){
    		$res[] = $heap->extract();
    	}
    	
    	return $res;
    }
    
    $arr = array(2,5,9,1,4,7,3,4,6,0,1,2,4,6,8,9,2,3);
    $arr = splHeapSort($arr);
    print_r($arr);
    
    ?>
    

      什么!!!这么简单??对,就是这么简单,不要问为什么,强大,任性!

  • 相关阅读:
    BS文件夹上传操作(一)
    ext.net 开发学习— 2012 上半年 总结
    C#泛型泛型方法
    C#泛型泛型类
    文件读取,保存操作
    itools下载链接被360警告:虚假招聘网站
    读书推荐:《wordpresss博客建站与经营》
    Net CF简单介绍
    木杉大话微软手机系统
    wp7和wp8的区别
  • 原文地址:https://www.cnblogs.com/taijun/p/4211515.html
Copyright © 2011-2022 走看看