PHP 插入排序、选择排序、快速排序、冒泡排序、二分查找(递归与非递归)

1.插入排序

/*
 * Notes: 插入排序分两块,已排序块与未排序块,每次从未排序块拿出一个数,跟已排序块的数据进行比较,进行数据的插入
 * @param $arr array 未排序的数组
 * return 已排序的数组
 */
function insertSort($arr) 
{
	//循环数组,从第二个开始,默认第一个为已排序区
    for ($i = 1; $i < count($arr); $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;
}

2.选择排序

/*
 * Notes: 选择排序,从第一个数开始,拿后面的数跟它进行比较,如果比它小则两个数交换位置,以此类推,一直到最后一个数
 * @param: $arr array 未排序的数组
 * return 已排序的数组
 */
function selectSort($arr)
{
    //循环数组,从第一个开始
    for ($i = 0; $i < count($arr); $i++) {
        $k = $i;
        //从后面一个数开始,跟拿出来的数进行比较
        for ($j = $i + 1; $j < count($arr); $j++) {
            //如果后面的数小于前面的数,则拿小的那个数的key
            if ($arr[$j] < $arr[$k]) {
                $k = $j;
            }
        }
        //如果有数比前面的小,则进行数据交换
        if ($k != $i) {
            $temp = $arr[$i];
            $arr[$i] = $arr[$k];
            $arr[$k] = $temp;
        }
    }
    //返回已排好序的数组
    return $arr;
}

3.快速排序

/*
 * Notes: 快速排序
 * @param: $arr 未做排序的数组
 * return 返回已排好序的数组
 */
function quick_sort($arr)
{
    $n = count($arr);
    //如果数组长度小于等于1,直接返回数组
    if ($n <= 1) {
        return $arr;
    }
    //首先拿数组第一个(在数组中键值为0)值做为中间值
    $key = $arr[0];
    //初始化两个数组,用于接收小于中间值和大于中间值的数据
    $left_arr = array();
    $right_arr = array();
    //从数组第二个数开始循环(在数组中键值为1)进行判断比较
    for ($i = 1; $i < $n; $i++) {
        if ($arr[$i] <= $key) { //数值小于中间值时,将数值放入左侧数组中
            $left_arr[] = $arr[$i];
        } else { //数值大于中间值时,将数值放入右侧数组中
            $right_arr[] = $arr[$i];
        }
    }
    //递归排序划分好的2边
    $left_arr = quick_sort($left_arr);
    $right_arr = quick_sort($right_arr);
    //合并数组
    return array_merge($left_arr, array($key), $right_arr);
}

4.冒泡排序

/*
 * Notes: 冒泡排序,依次比较两个数进行排序,顺序(小数往前放,大数往后放),逆序(大数往前放,小数往后放)
 * @param: $arr 待排序数组
 * return 已排好序的数组
 */
function bubbleSort($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;
}

5.二分查找(非递归)

/*
 * Notes: 二分查找(非递归),先取数组中间数进行比较,若查找数值比这个数小,则往前查,否则往后查
 * @param: $arr 已经排好序的数组
 * @param: $low 首位置
 * @param: $high 尾位置
 * @param: $value 需要查找的数
 * return 查到的数组中的键值,未查到则返回false
 */
function binSearch($arr, $low, $high, $value) {
    //判断当首位置值小于等于尾位置值
    while($low <= $high) {
        //取中间值
        $mid = floor(($low + $high) / 2);
        if($value == $arr[$mid]) { //当需要查找的数值与数组中的数值相等时,则返回键值
            return $mid;
        } elseif ($value < $arr[$mid]) { //当需要查找的数值小于数组中的数组时,尾位置值-1
            $high = $mid - 1;
        } else { //其余的则首位置+1
           $low = $mid + 1; 
        }
    }
    return false;
}

6.二分查找(递归)

/*
 * Notes: 二分查找(递归),先取数组中间数进行比较,若查找数值比这个数小,则往前查,否则往后查
 * @param: $arr 已经排好序的数组
 * @param: $low 首位置
 * @param: $high 尾位置
 * @param: $value 需要查找的数
 * return 查到的数组中的键值,未查到则返回false
 */
function binSearch($arr, $low, $high, $value)
{
    if ($low <= $high) { //当首位置大于尾位置时,返回false
        //取中间值
        $mid = floor(($low + $high) / 2);
        if ($value == $arr[$mid]) { //当需要查找的数值与数组中的数值相等时,则返回键值
            return $mid;
        } elseif ($value < $arr[$mid]) { //当需要查找的数值小于数组中的数组时,尾位置值-1,回调
            return binSearch($arr, $low, $mid - 1, $value);
        } else { //其余的则首位置+1,回调
            return binSearch($arr, $mid + 1, $high, $value);
        }
    }
    return false;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值