PHP实现常见查找和排序算法

1、      冒泡排序

思想:

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

示例:

 

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)。

 

?

1

2

3

4

5

6

7

8

9

10

11

12

13

function bubble_sort($arr) {

    $n=count($arr);

    for($i=0;$i<$n-1;$i++){

        for($j=$i+1;$j<$n;$j++) {

            if($arr[$j]<$arr[$i]) {

                $temp=$arr[$i];

                $arr[$i]=$arr[$j];

                $arr[$j]=$temp;

            }

        }

    }

    return $arr;

}

2、归并排序

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

function Merge(&$arr, $left, $mid, $right) {

  $i = $left;

  $j = $mid + 1;

  $k = 0;

  $temp = array();

  while ($i <= $mid && $j <= $right)

  {

    if ($arr[$i] <= $arr[$j])

      $temp[$k++] = $arr[$i++];

    else

      $temp[$k++] = $arr[$j++];

  }

  while ($i <= $mid)

    $temp[$k++] = $arr[$i++];

  while ($j <= $right)

    $temp[$k++] = $arr[$j++];

  for ($i = $left, $j = 0; $i <= $right; $i++, $j++)

    $arr[$i] = $temp[$j];

}

 

function MergeSort(&$arr, $left, $right)

{

  if ($left < $right)

  {

    $mid = floor(($left + $right) / 2);

    MergeSort($arr, $left, $mid);

    MergeSort($arr, $mid + 1, $right);

    Merge($arr, $left, $mid, $right);

  }

}

3、二分查找-递归

?

1

2

3

4

5

6

7

8

9

10

11

12

13

function bin_search($arr,$low,$high,$value) {

    if($low>$high)

        return false;

    else {

        $mid=floor(($low+$high)/2);

        if($value==$arr[$mid])

            return $mid;

        elseif($value<$arr[$mid])

            return bin_search($arr,$low,$mid-1,$value);

        else

            return bin_search($arr,$mid+1,$high,$value);

    }

}

4、二分查找-非递归

?

1

2

3

4

5

6

7

8

9

10

11

12

function bin_search($arr,$low,$high,$value) {

    while($low<=$high) {

        $mid=floor(($low+$high)/2);

        if($value==$arr[$mid])

            return $mid;

        elseif($value<$arr[$mid])

            $high=$mid-1;

        else

            $low=$mid+1;

    }

    return false;

}

5、快速排序

思想:

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

时间复杂度:

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

 

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

function quick_sort($arr) {

    $n=count($arr);

    if($n<=1)

        return $arr;

    $key=$arr[0];

    $left_arr=array();

    $right_arr=array();

    for($i=1;$i<$n;$i++) {

        if($arr[$i]<=$key)

            $left_arr[]=$arr[$i];

        else

            $right_arr[]=$arr[$i];

    }

    $left_arr=quick_sort($left_arr);

    $right_arr=quick_sort($right_arr);

    return array_merge($left_arr,array($key),$right_arr);

}

6、选择排序

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

示例:

[初始关键字] [49 38 65 97 76 13 27 49]
第一趟排序后 13 [38 65 9776 49 27 49]
第二趟排序后 13 27 [65 9776 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),不稳定排序,适合规模比较小的

 

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

function select_sort($arr) {

    $n=count($arr);

    for($i=0;$i<$n;$i++) {

        $k=$i;

        for($j=$i+1;$j<$n;$j++) {

           if($arr[$j]<$arr[$k])

               $k=$j;

        }

        if($k!=$i) {

            $temp=$arr[$i];

            $arr[$i]=$arr[$k];

            $arr[$k]=$temp;

        }

    }

    return $arr;

}

7、插入排序

思想:

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

示例:

[初始关键字] [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)。因而,插入排序不适合对于数据量比较大的排序应用。但是,如果需要排序的数据量很小,例如,量级小于千,那么插入排序还是一个不错的选择。

 

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

function insertSort($arr) {

    $n=count($arr);

    for($i=1;$i<$n;$i++) {

        $tmp=$arr[$i];

        $j=$i-1;

        while($arr[$j]>$tmp) {

            $arr[$j+1]=$arr[$j];

            $arr[$j]=$tmp;

            $j--;

            if($j<0)

                break;

        }

    }

    return $arr;

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值