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);
    
    ?>
    

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

  • 相关阅读:
    Using Resource File on DotNet
    C++/CLI VS CSharp
    JIT VS NGen
    [Tip: disable vc intellisense]VS2008 VC Intelisense issue
    UVa 10891 Game of Sum(经典博弈区间DP)
    UVa 10723 Cyborg Genes(LCS变种)
    UVa 607 Scheduling Lectures(简单DP)
    UVa 10401 Injured Queen Problem(简单DP)
    UVa 10313 Pay the Price(类似数字分解DP)
    UVa 10635 Prince and Princess(LCS N*logN)
  • 原文地址:https://www.cnblogs.com/taijun/p/4211515.html
Copyright © 2011-2022 走看看