排序严格来说不属于数据结构,而应该归为算法,因为数据结构是指数据与数据之间的关系,而排序参与其中更多的是改变数据的状态。于是,我们开始用PHP来谈算法。其实简介里有句话说得好,“没有必要重新发明轮子”,所以我就引用别人的文章作为这篇文章的引用,直观感受整理过程。同时补充自己的理解和代码+注释(其实很多话都在注释里)。其实,如果你是一个纯PHP开发者,在日常开发中,封装的数据结构和算法有很多。之所以要自己实现函数库,是因为有些人是为了装逼,当然也有一些人是为了理解更复杂的逻辑和计算机执行的底层规则,从而提高自己的编程能力。我是为了考试而做的,这也是一种能力。原文引用自:【直观学习排序算法】几种常用排序算法的直观直观体验1快速排序简介: 快速排序是TonyHall开发的一种排序算法。平均而言,对n项进行排序需要O(nlogn)次比较。在最坏的情况下需要进行O(n2)次比较,但这并不常见。事实上,快速排序通常比其他OO(nlogn)算法快得多,因为它的内部循环可以在大多数架构和大多数真实世界数据上有效地实现,它可以决定设计选择,减少二次项的可能性在规定的时间内。步骤:从数组中选取一个元素,称为“pivot”,对数组重新排序,所有小于pivot值的元素都放在pivot前面,所有大于pivot值的元素都放在pivot后面(相同数可以去任何一边)。此分区退出后,基准测试位于序列的中间。这称为分区操作。对元素小于基值的子数组和元素大于基值的子数组进行递归排序。排序效果:代码实现:=$pivot){$high--;#如果数组的高值端(假设)大于pivot单元,则高值端从后向前移动,说明它确实是高值而不交换}swap($arr,$low,$high);#直到高值端小于等于Pivotunit,然后交换元素,将较大的值放在高值端,较小的值放在低值端。请注意,交换数组单元while($low<$high&&$arr[$low]<=$pivot){$low++;#如果数组的lowvalueend(假设)小于pivotunit(注意,因为low和high之前已经交换过值,所以当前的$arr[$low]不等于原来的值),那么高值端从后往前移动}swap($arr,$low,$high);#直到低值端大于等于pivot单位,然后交换元素,将值大的放在高值端,值小的放在低值端}return$low;#由于低位保持++,高位保持--,它们在某处相遇,即主元下标,return}$arr=[4,7,3,2,7,6,8];$res=main($arr);echo"
";print_r($res);2归并排序介绍: 归并排序(Mergesort,台译:归并排序)是一种基于归并操作的高效排序算法这个算法是分治法(DivideandConquer)一个非常典型的应用步骤:申请空间,使之成为两个排序序列之和的大小,这个空间用来存放合并后的序列,并设置两个指针,初始位置分别为两个排序序列的起始位置比较两个指针指向的元素,选择比较小的元素放入合并空间,将指针移动到下一个位置重复步骤3,直到指针到达序列末尾将另一个序列的剩余元素全部复制到合并序列的末尾排序效果:代码实现:";print_r($res);3堆排序介绍: Heapsort是指利用堆的数据结构设计的一种排序算法。堆是一种近似完全二叉树的结构,同时满足堆的性质:即子节点的键值或索引总是小于(或大于)其父节点。步骤:这里补充一下原文a。构造一个大(小)顶堆b.每构造一个顶堆,就可以得到最大值或最小值,与尾节点交换,取出c。循环构建顶堆并对值进行排序效果:代码实现:0;$s--){createHeap($arr,$s,$m);}return$arr;}/***TODO:构建一个大的顶层堆*@param$arrArray待构造的数组*@param$sint开始下标(二叉树中最后一个有两个子节点的父节点编号)*@param$示例mint数组长度:50/\3060/\7020(这个不满足堆的定义,需要重构)*/functioncreateHeap(&$arr,$s,$m){$temp=$arr[$s];#二叉树中最后一个有两个子节点的父节点for($i=2*$s;$i<$m;$i*=2){if($arr[$i]<$arr[$i+1]){#i=2si+1=2s+1是s节点的左右孩子节点,先比较左右子节点的大小,找出较大的值$i++;}if($temp>=$arr[$i]){#然后比较较大的值和父节点,如果父节点太大,则跳出循环break;}#如果父节点小,交换父节点和子节点的值(不额外增加辅助空间,空间复杂度O(1))$arr[$s]=$arr[$i];$s=$i;}$arr[$s]=$temp;}/***TODO:堆排序*/functionheapSort(&$arr){$length=count($arr)-1;for($i=$length;$i>1;$i--){#这里i不需要和自己交换,所以不需要等于1swap($arr,1,$i);createHeap($arr,1,$i);#这里注意数组的长度会递减}return$arr;}$data=[0,5,1,9,3,7,4,8,6,2];$res=main($data);//$heapArr=heapSort($res);echo"";print_r($data);4选择排序介绍: 选择排序(Selectionsort)是一种简单直观的排序算法。其工作原理如下。先在未排序的序列中找到最小的元素,将其存放在已排序序列的开头,然后继续从剩余未排序的元素中查找最小的元素,放在已排序序列的末尾。依此类推,直到所有元素都排序完毕。排序效果:详细过程:5冒泡排序介绍: 冒泡排序(BubbleSort,台湾翻译:冒泡排序或冒泡排序)是一种简单的排序算法。它迭代遍历要排序的数组,一次比较两个元素,如果顺序错误则交换它们。重复访问序列的工作,直到不需要交换,即序列已经排序。这个算法的名字来源于这样一个事实,即较小的元素会通过交换慢慢“浮”到序列的顶部。步骤:比较相邻元素。如果第一个大于第二个,则交换它们。对每对相邻元素执行相同的操作,从开头的第一对到结尾的最后一对。此时,最后一个元素应该是最大的数。对除最后一个元素之外的所有元素重复上述步骤。每次对越来越少的元素继续重复上述步骤,直到没有要比较的数字对。排序效果:详细过程:6插入排序介绍: 插入排序(InsertionSort)算法描述是一种简单直观的排序算法。它的工作原理是构造一个有序的序列,对于未排序的数据,在已排序的序列中从后往前扫描,找到对应的位置并插入。在插入排序的实现中,通常使用原地排序(即只需要使用O(1)额外空间的排序),所以在从后往前扫描的过程中,需要反复移动逐步向后排序元素,为最新元素提供插入空间。步骤:从第一个可以认为已经排序的元素开始,取出下一个元素,在已排序元素的序列中从后往前扫描如果元素(已排序)大于新元素,移动元素到下一个位置重复步骤3,直到找到排序后的元素小于等于新元素的位置将新元素插入到该位置重复步骤2排序效果:(还没有)详细过程:7山排序介绍: 希盼Err排序,又称自减自增排序算法,是插入排序的高速稳定改进版。 希尔排序是基于插入排序的以下两个性质,提出了一种改进方法:插入排序在对几乎已排序的数据进行操作时效率很高,即可以达到线性排序的效率,但插入排序是一般说是低效的,因为插入排序一次只能移动数据一位。排序效果:有空再改。