ca88编程PHP排序算法之堆排序(Heap Sort)实例详解

作者:ca88编程

正文实例陈说了PHP落成的堆排序算法。分享给我们供大家参考,具体如下:

PHP落成的堆排序算法详解,堆排序算法详解

正文实例陈说了PHP达成的堆排序算法。分享给我们供我们参谋,具体如下:

经验

干活了,面试小编专业这家百货店时被技巧面打击得拾壹分,因为自个儿的数据结构等基础学得实在太差,即使原本是想做设计师的说。。。可是看在PHP写得还集中的份上能来实习了,但依然决意恶补一下基础。 其实自身前面也着实感到到到了基础的最主要,一些比较深的东西都相比底层,不学好根本无法实行。像本人事先用PHP做websocket,就拉拉扯扯到数据包、数据帧等概念,搞不清楚,连数据都无法管理,还得后来补。所以自个儿打算再次学一下数据结构,算法,互联网等基础知识,也在此跟我们提个醒,别像自身同样走反了样子,乃至到驾驭过来就曾经晚了。

后天的话一下被问到的堆排序的主题材料,当时被问到时,连完全二叉树的概念都忘了。可是万幸自个儿还应该有一丢丢数据结构基础,看了点资料也是有个别明白了,所以想用PHP写一下二叉树的堆排序,顺便也复习下二叉树,堆等数据结构。

堆(heap)是Computer科学中一类特别的数据结构的统称,平日是一个能够被看做一棵树的数组对象。

堆{k1,k2,ki,…,kn} (ki <= k2i,ki <= k2i 1)|(ki >= k2i,ki >= k2i 1), (i = 1,2,3,4...n/2)

关于堆:

堆中某些节点的值总是非常的小于或一点都不小于其父节点的值;
堆总是一棵完全二叉树(下边)。
将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。

全然二叉树

聊到堆排序,就必须提完全二叉树,这么些基本概念在网络随地可知,笔者摘了个最轻松易行的。。

统统二叉树:除最终一层外,每一层上的节点数均达标最大值;在结尾一层上只缺少左侧的多少结点。

自身要好计算以为,正是因为有下边八个特点,

1. 只同意最终一层有空缺结点且空缺在右边,即叶子结点只可以在等级次序最大的两层上出现(存款和储蓄格局的法规性);

  1. 若i>1,tree的老人家为tree[i div 2](其父子结点值的规律性);

才使得其张开排序特别有益。

堆排序

堆排序求升序用大顶堆,求降序用小顶堆。

本例用求降序的小顶堆来剖析。

堆排序步骤如下:

1、大家将数据(49、38、65、97、76、13、27、50)创立二个数组$arr;
2、用数组$arr建立四个小顶堆(主要步骤,会在代码注释里解释,下图是用二个数组构造建设小顶堆的经过);
3、将堆的根(最小的要素)与终极三个卡片沟通,并将堆长度减一,跳到第二步;
4、重复2-3步,直到堆中唯有三个结点,排序完毕。

ca88编程 1

堆排序的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;
}

上面是排序的最终结果:

ca88编程 2

越来越多关于PHP相关内容感兴趣的读者可查阅本站专题:《php排序算法总括》、《PHP数据结构与算法教程》、《php程序设计算法总计》、《PHP数组(Array)操作技能大全》、《php字符串(string)用法总计》、《PHP常用遍历算法与本事计算》及《PHP数学生运动算本事总计》

指望本文所述对我们PHP程序设计有着帮忙。

本文实例叙述了PHP完成的堆排序算法。共享给我们供我们参照他事他说加以考查,具体如下: 经验 专业了,面试...

经验

干活了,面试作者职业这家公司时被技能面打击得那二个,因为自身的数据结构等基础学得实在太差,即使原来是想做设计员的说。。。不过看在PHP写得还汇集的份上能来实习了,但仍旧痛下决心恶补一下基础。 其实自身前边也确实认为到到了基础的关键,一些相比深的事物都相比底层,不学好根本没办法举行。像本身事先用PHP做websocket,就牵涉到数据包、数据帧等概念,搞不清楚,连数据都没有办法管理,还得后来补。所以自身准备再一次学一下数据结构,算法,网络等基础知识,也在此跟大家提个醒,别像本身同一走反了大方向,乃至到了解过来就早就晚了。

明日来讲一下被问到的堆排序的难点,当时被问到时,连完全二叉树的概念都忘了。但是万幸自个儿还或然有一丢丢数据结构基础,看了点资料也有个别驾驭了,所以想用PHP写一下二叉树的堆排序,顺便也复习下二叉树,堆等数据结构。


本文实例叙述了PHP排序算法之堆排序(Heap Sort)。分享给咱们供大家参谋,具体如下:

经验

堆(heap)是计算机科学中一类特殊的数据结构的统称,平时是三个能够被当做一棵树的数组对象。

堆{k1,k2,ki,…,kn} (ki <= k2i,ki <= k2i 1)|(ki >= k2i,ki >= k2i 1), (i = 1,2,3,4...n/2)

关于堆:

  • 堆中有些节点的值总是一点都不大于或不低于其父节点的值;
  • 堆总是一棵完全二叉树(上面)。
  • 将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。

算法引入:

干活了,面试作者专门的学业这家商城时被手艺面打击得特别,因为自个儿的数据结构等基础学得实在太差,尽管原本是想做设计员的说。。。然则看在PHP写得还聚焦的份上能来实习了,但依旧痛下决心恶补一下基础。 其实自身前边也确确实实感觉到了基础的显要,一些相比深的东西都相比较底层,不学好根本没办法举办。像本身事先用PHP做websocket,就推推搡搡到数据包、数据帧等概念,搞不清楚,连数据都无法管理,还得后来补。所以自身筹划再一次学一下数据结构,算法,网络等基础知识,也在此跟我们提个醒,别像自个儿同样走反了趋势,乃至到了解过来就已经晚了。

一心二叉树

谈起堆排序,就务须提完全二叉树,那一个基本概念在互连网各处都以,笔者摘了个最简便易行的。。

全然二叉树:除最终一层外,每一层上的节点数平均高度达最大值;在终极一层上只贫乏左侧的几何结点。

自身本人总计认为,就是因为有下边八个特色,

  • 只同意最终一层有空缺结点且空缺在侧边,即叶子结点只好在档期的顺序最大的两层上冒出(存款和储蓄方式的准则性);
  • ca88编程,若i>1,tree的家长为tree[i div 2](其老爹和儿子结点值的规律性);

才使得其进展排序特别有利于。


在此间笔者一直援引《高调数据结构》里面包车型地铁启幕:

明天来讲一下被问到的堆排序的标题,当时被问到时,连完全二叉树的定义都忘了。然而好在小编还大概有一丢丢数据结构基础,看了点资料也某些了然了,所以想用PHP写一下二叉树的堆排序,顺便也复习下二叉树,堆等数据结构。

堆排序

堆排序求升序用大顶堆,求降序用小顶堆。

本例用求降序的小顶堆来深入分析。

堆排序步骤如下:

1、大家将数据(49、38、65、97、76、13、27、50)创建三个数组$arr;

2、用数组$arr创建二个小顶堆(首要步骤,会在代码注释里解释,下图是用三个数组构造建设小顶堆的历程);

3、将堆的根(最小的因素)与终极一个叶子交流,并将堆长度减一,跳到第二步;

4、重复2-3步,直到堆中唯有三个结点,排序完结。

ca88编程 3


在日前讲到 差不离选取排序 ,它在待排序的 n 个记录中挑选三个比相当的小的记录需求相比 n - 1 次,本来那也足以明白,查找第一个数据须求相比较这么数次是正规的,不然如何晓得他是纤维的笔录。

堆排序的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;
}

上面是排序的终极结果:

ca88编程 4


2017.12.07 添加:

堆用来进行全排序,时间复杂度是 O(nlogn)

而快排用来全排序,平均时间复杂度也是 O(nlogn)

但堆排序能够用来求 TopK 时,堆的时刻复杂度为 O(Klog2(n),因为它只须求打开 K 轮排序就可以。 

 

一旦你感到本博文对你有救助,您能够引入或关怀自己,要是你有何样难点,能够在江湖留言研究,多谢。

惋惜的是,那样的操作并从未把每便的可比结实保存下去,在后一趟的比较重,有为数不少比较在前一趟已经做过了,但鉴于前一趟排序时未保存这么些相比结实,所未来一趟排序时又再一次施行了那么些相比操作,由此记录的相比较次数比较多。

堆(heap)是Computer科学中一类特殊的数据结构的统称,经常是一个可以被当做一棵树的数组对象。

假如得以成功每回在选拔到微小记录的同有时候,并基于相比结实对任何记录做出相应的调动,那样排序的完整成效就能相当高了。而堆排序,就是对简易选取排序举办的一种革新,这种革新的功效是极其理解的。

堆{k1,k2,ki,…,kn} (ki <= k2i,ki <= k2i 1)|(ki >= k2i,ki >= k2i 1), (i = 1,2,3,4...n/2)

着力思维:

关于堆:

在介绍堆排序以前,大家先来介绍一下堆:

本文由ca88发布,转载请注明来源

关键词: ca88网址 php 算法 堆排序 二叉树