php常见的几种排序以及二分法查找

<?php

1.插入排序

思想:

每次将一个待排序的数据元素插入到前面已经排好序的数列中,使数列依然有序,知道待排序数据元素全部插入完为止。

示例:

[初始关键字] [49] 38 65 97 76 13 27 49
J=2(38) [38 49] 65 97 76 13 27 49
J=3(65) [38 49 65] 97 76 13 27 49
J=4(97) [38 49 65 97] 76 13 27 49
J=5(76) [38 49 65 76 97] 13 27 49
J=6(13) [13 38 49 65 76 97] 27 49
J=7(27) [13 27 38 49 65 76 97] 49
J=8(49) [13 27 38 49 49 65 76 97]

时间复杂度:

如果目标是把n个元素的序列升序排列,那么采用插入排序存在最好情况和最坏情况。最好情况就是,序列已经是升序排列了,在这种情况下,需要进行的比较操作需(n-1)次即可。最坏情况就是,序列是降序排列,那么此时需要进行的比较共有n(n-1)/2次。插入排序的赋值操作是比较操作的次数加上 (n-1)次。平均来说插入排序算法的时间复杂度为O(n^2)。因而,插入排序不适合对于数据量比较大的排序应用。但是,如果需要排序的数据量很小,例如,量级小于千,那么插入排序还是一个不错的选择。

//插入排序
function insertSort($arr){
$count=count($arr);
for($i=1;$i<$count;$i++){
$tem=$arr[$i];
$j=$i-1;
while ($arr[$j]>$tem){
$arr[$j+1]=$arr[$j];
$arr[$j]=$tem;
$j--;
}
}
return  $arr;

}

2.选择排序

思想:每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。

示例:

[初始关键字] [49 38 65 97 76 13 27 49]
第一趟排序后 13 [38 65 97 76 49 27 49]
第二趟排序后 13 27 [65 97 76 49 38 49]
第三趟排序后 13 27 38 [97 76 49 65 49]
第四趟排序后 13 27 38 49 [49 97 65 76]
第五趟排序后 13 27 38 49 49 [97 97 76]
第六趟排序后 13 27 38 49 49 76 [76 97]
第七趟排序后 13 27 38 49 49 76 76 [ 97]
最后排序结果 13 27 38 49 49 76 76 97

时间复杂度:

时间复杂度为o(n2),不稳定排序,适合规模比较小的

//选择排序
function selectSort($arr){
$count = count($arr);
for($i=0;$i<$count-1;$i++){
$k=$i;
for($j=$i+1;$j<$count;$j++){
if($arr[$k]>$arr[$j])
$k=$j;
}
$temp=$arr[$i];
$arr[$i]=$arr[$k];
$arr[$k]=$temp;
}
return $arr;
}

3.冒泡排序

思想:

两两比较待排序数据元素的大小,发现两个数据元素的次序相反时即进行交换,直到没有反序的数据元素为止。

示例:

49 13 13 13 13 13 13 13 
38 49 27 27 27 27 27 27
65 38 49 38 38 38 38 38
97 65 38 49 49 49 49 49
76 97 65 49 49 49 49 49
13 76 97 65 65 65 65 65
27 27 76 97 76 76 76 76
49 49 49 76 97 97 97 97

时间复杂度:

该算法的时间复杂度为O(n2)。但是,当原始关键字序列已有序时,只进行一趟比较就结束,此时时间复杂度为O(n)。

//冒泡排序
function bubbleSort($arr){
$count = count($arr);
if ($count <= 0) return false;
for($i=0;$i<count($arr);$i++){
$flag = false;    //本趟排序开始前,交换标志应为假
for($j=count($arr)-1;$j>$i;$j--){
if($arr[$j-1]>$arr[$j]){
$temp=$arr[$j-1];
$arr[$j-1]=$arr[$j];
$arr[$j]=$temp;
$flag=true;
}
}
if(! $flag)//本趟排序未发生交换,提前终止算法
return $arr;
}
//return $arr;
}

4.快速排序

思想:

通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

时间复杂度:

快速排序主体算法时间运算量约 O(log2n) ,划分子区函数运算量约 O(n) ,所以总的时间复杂度为 O(nlog2n) ,它显然优于冒泡排序 O(n2). 可是算法的优势并不是绝对的。试分析,当原文件关键字有序时,快速排序时间复杂度是 O(n2), 这种情况下快速排序不快。而这种情况的冒泡排序是 O(n), 反而很快。在原文件记录关键字无序时的多种排序方法中,快速排序被认为是最好的一种排序方法。

//快速排序
function quickSort($arr){
if(count($arr)<=1)
return $arr;
$key=$arr[0];
$left_arr=array();
$right_arr=array();
for($i=1;$i<count($arr);$i++){
if($arr[$i]<=$key){
$left_arr[]=$arr[$i];
}else{
$right_arr[]=$arr[$i];
}
}
$left_arr=quickSort($left_arr);
$right_arr=quickSort($right_arr);
return array_merge($left_arr,array($key),$right_arr);
}

$arr=array(49,38,65,97,76,13,27,49);
print_r(quickSort($arr));

// 二分法查找
function binarysearch($arr, $value, $start = 0, $end = NULL) {
if($end == NULL) $end = count($arr) - 1;
$index = floor(($start+$end)/2);
$base = $arr[$index];
if($value < $base) return binarysearch($arr, $value, $start, $index-1);
else if($value > $base) return binarysearch($arr, $value, $index+1, $end);
else return $index;
}

$arr = array(1, 3, 5, 6, 7, 8, 10, 12, 14, 16, 18, 20);
$value = 8;
echo binarysearch($arr, $value);

时间: 2024-12-22 04:21:05

php常见的几种排序以及二分法查找的相关文章

Java常见的几种排序算法-插入、选择、冒泡、快排、堆排等

本文就是介绍一些常见的排序算法.排序是一个非常常见的应用场景,很多时候,我们需要根据自己需要排序的数据类型,来自定义排序算法,但是,在这里,我们只介绍这些基础排序算法,包括:插入排序.选择排序.冒泡排序.快速排序(重点).堆排序.归并排序等等.看下图: 给定数组:int data[] = {9,2,7,19,100,97,63,208,55,78} 一.直接插入排序(内部排序.O(n2).稳定) 原理:从待排序的数中选出一个来,插入到前面的合适位置. [java] view plain copy

常见的8种排序算法

部分转自互联网...... 下面要讲到的8种排序都属于内部排序,既在内存中完成,主要从理论原理方面来分析的.    插入排序 ①直接插入排序 例:六个数12 15 9 20  6 31 24 用直接插入排序,如下图: 思路: 第一步:从给出的六个数中,随便拿出一个数,比如12,形成一个有序的数据序列(一个数当然是有序的数据序列了,不看12之外的数,就当其他的数不存在): 第二步:从剩下的五个数中挑出一个数来,比如15,和刚才的12作比较,12<15,因此,放在12后面,形成数据序列12 15:

常见的几种排序算法-插入、选择、冒泡、快排、堆排等

排序是一个非常常见的应用场景,很多时候,我们需要根据自己需要排序的数据类型,来自定义排序算法,但是,在这里,我们只介绍这些基础排序算法,包括:插入排序.选择排序.冒泡排序.快速排序(重点).堆排序.归并排序等等.看下图: 给定数组:int data[] = {9,2,7,19,100,97,63,208,55,78} 一.直接插入排序(内部排序.O(n2).稳定) 原理:从待排序的数中选出一个来,插入到前面的合适位置. package com.xtfggef.algo.sort; public

常见的几种排序

快速排序 从数列中挑出一个元素,称为 "基准"(pivot),重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边).在这个分区退出之后,该基准就处于数列的中间位置.这个称为分区(partition)操作.递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序. 排序效果: int PartSort(int* a, int left, int right)   //每步的排序 {     int key =

c语言常见的几种排序方法总结

一:选择排序和冒泡排序 这两种排序比较简单,直接贴出代码: 1 #include <stdio.h> 2 3 void choose_sort(int *arr, int n); 4 void bubble_sort(int *arr, int n); 5 void show(int *arr, int n); 6 7 int main() 8 { 9 int arr[10] = {10, 8, 3, 15, 18, 16, 11, 9, 7, 6}; 10 11 /*选择排序*/ 12 ch

Java常用排序算法+程序员必须掌握的8大排序算法+二分法查找法

Java 常用排序算法/程序员必须掌握的 8大排序算法 本文由网络资料整理转载而来,如有问题,欢迎指正! 分类: 1)插入排序(直接插入排序.希尔排序) 2)交换排序(冒泡排序.快速排序) 3)选择排序(直接选择排序.堆排序) 4)归并排序 5)分配排序(基数排序) 所需辅助空间最多:归并排序 所需辅助空间最少:堆排序 平均速度最快:快速排序 不稳定:快速排序,希尔排序,堆排序. 先来看看 8种排序之间的关系: 1.直接插入排序 (1)基本思想:在要排序的一组数中,假设前面(n-1)[n>=2]

常见的八种排序

1.直接插入排序 直接插入排序的核心思想就是:将数组中的所有元素依次跟前面已经排好的元素相比较,如果选择的元素比已排序的元素小,则交换,直到全部元素都比较过.因此,从上面的描述中我们可以发现,直接插入排序可以用两个循环完成: 第一层循环:遍历待比较的所有数组元素 第二层循环:将本轮选择的元素(selected)与已经排好序的元素(ordered)相比较.如果:selected > ordered,那么将二者交换 2.希尔排序 希尔排序的算法思想:将待排序数组按照步长gap进行分组,然后将每组的元

常见的三种排序

交换排序 假设有一个数组nums,长度为5,要对它进行升序排序,交换排序总体思路是: 在下标0-4范围内,将该范围内最小的数字提到下标0 在下标1-4范围内,将该范围内最小的数字提到下标1 在下标2-4范围内,将该范围内最小的数字提到下标2 在下标3-4范围内,将该范围内最小的数字提到下标3 排序完成! 写成代码就应该是: for (int i = 0; i < 4; i++){ //在 i-4 范围内,将该范围内最小的数字提到i} 这是假设nums数组长度为5,如果nums数组长度为6呢?用同

博客一,常见的几种排序算法的Java实现

一.插入排序 算法导论上有很形象的比喻,把插入排序类比成扑克牌,默认你手里本身拥有的第一张是有序的,第二章和第一张对比后决定其位置,以此类推.代码如下: 1 public class InsertSort { 2 public void insertSort(int[] a){ 3 if(a==null||a.length==0||a.length==1){ 4 return ; 5 } 6 //i代表已有序的数组元素的边界, 7 for(int i = 0 ; i<a.length-1 ;i+