PHP 4 major sorting algorithms and binary search

Insertion sort

   1. Starting from the first element , the element can be considered to have been sorted
   2. Take out the next element and compare it from back to front in the sequence of sorted elements
   3. If the element (sorted) is greater than the new element, it Element moves to the next position

/**
     * 插入排序
     */
    public function Insert_sort($arr=array(5,2,7,1,3)){
        $count=count($arr);
        for($i=1;$i<$count;$i++){
            $j=$i-1;
            $temp=$arr[$i];   //临时比较元素
            while($j>=0){    //从后往前逐个比较元素大小
                if($arr[$j]>$temp){      //临时比较元素比较小则交换前后元素位置
                    $arr[$j+1]=$arr[$j];
                    $arr[$j]=$temp;
                }
                $j--;
            }
            var_dump($arr);echo "<br>";
        }
        return $arr;
    }

 

Simple selection sort

thought:

1) Loop n times, find the smallest element for element exchange each time  .

/**
     * 简单排序
     * 循环n次,每次找到最小的元素进行元素交换
     */
    public function Select($arr=array(2,16,8,6,3,19)){
        $count=count($arr);
        for($i=0;$i<=$count;$i++){
            $min=$i;
            for($j=$i+1;$j<$count;$j++){    //从未比较的元素开始循环
                if($arr[$j]<$arr[$min]){
                    $min=$j;    //比较到小元素则记录其下标
                }
            }
            if($min!=$i){    //使用临时变量交换最小元素
                $temp = $arr[$min];
                $arr[$min] = $arr[$i];
                $arr[$i] = $temp;
            }
        }
        return $arr;
    }

 

Bubble Sort

Ideas:

1) The first loop controls the number of loops, the length of the array is n-1 times (the worst result is to compare n-1 times to get the result)

2) The second loop compares each element of the array, and the next element is smaller than the previous element and the position is exchanged (a temporary variable $tmp is required )
 

 

function bubbleSort($arr){  
        $count=count($arr);
        #对于一个长度为N的数组,我们需要排序 N-1 轮,每 i 轮 要比较 N-i 次。对此我们可以用双重循环语句,外层循环控制循环轮次,内层循环控制每轮的比较次数。
        for($i=1;$i<$count;$i++){ 
            for($k=0;$k<$count-$i;$k++){
                if($arr[$k]>$arr[$k+1]){
                    $tmp=$arr[$k+1];
                    $arr[$k+1]=$arr[$k];
                    $arr[$k]=$tmp;
                }
            }
        }
        return $arr;
}

 

Quick sort

Ideas: 
1) Select a reference element , usually the first element or the last element, 
2) Split the records to be sorted into two independent arrays through a sorting , where the element values ​​of the small array records are all higher than the reference element If the value is small, the element value recorded in the large array is larger than the reference value. 
3) Then the same method recursively sorts the large and small arrays until the entire sequence is ordered. 
4) Finally, merge small arrays, base elements, and large arrays

 /**
     * 快速排序
     */
    public function Quick_sort($arr = array(50, 43, 54, 62, 21, 66, 32, 78, 36, 76, 39,2)){
        //判断参数是否是一个数组
        if(!is_array($arr)) return false;

        //递归出口:递归至数组长度为1,则返回数组
        $length = count($arr);
        if($length<=1) return $arr;

        //数组元素有多个,则定义两个空数组
        $left = array();
        $right = array();

        //使用for循环遍历数组
        for($i=1; $i<$length; $i++) {
            $value = $arr[0] ; //把 第一个元素 当做 比较对象

            if($arr[$i] < $value){
                $left[]=$arr[$i];    //小于 比较对象放入 $left 数组
            }else{
                $right[]=$arr[$i];    //大于 比较对象放入 $right 数组
            }
        }

        //不断递归 $left、$right数组知道数组长度为1
        $left = $this->Quick_sort($left);
        $right = $this->Quick_sort($right);


        //将所有的结果合并
        return array_merge($left,$value,$right);
    }

 

Merge sort

Merge (Merge) sorting method is to merge two (or more) ordered lists into a new ordered list, that is, divide the sequence to be sorted into several ordered subsequences, and then divide the ordered subsequences Merge into an overall ordered sequence.

/**
* mergeSort 归并排序
* 是开始递归函数的一个驱动函数
* @param &$arr array 待排序的数组
*/
function mergeSort(&$arr) {
    $len = count($arr);//求得数组长度
 
    mSort($arr, 0, $len-1);
}
/**
* 实际实现归并排序的程序
* @param &$arr array 需要排序的数组
* @param $left int 子序列的左下标值
* @param $right int 子序列的右下标值
*/
function mSort(&$arr, $left, $right) {
 
    if($left < $right) {
        //说明子序列内存在多余1个的元素,那么需要拆分,分别排序,合并
        //计算拆分的位置,长度/2 去整
        $center = floor(($left+$right) / 2);
        //递归调用对左边进行再次排序:
        mSort($arr, $left, $center);
        //递归调用对右边进行再次排序
        mSort($arr, $center+1, $right);
        //合并排序结果
        mergeArray($arr, $left, $center, $right);
    }
}
 
/**
* 将两个有序数组合并成一个有序数组
* @param &$arr, 待排序的所有元素
* @param $left, 排序子数组A的开始下标
* @param $center, 排序子数组A与排序子数组B的中间下标,也就是数组A的结束下标
* @param $right, 排序子数组B的结束下标(开始为$center+1)
*/
function mergeArray(&$arr, $left, $center, $right) {
    //设置两个起始位置标记
    $a_i = $left;
    $b_i = $center+1;
    while($a_i<=$center && $b_i<=$right) {
        //当数组A和数组B都没有越界时
        if($arr[$a_i] < $arr[$b_i]) {
            $temp[] = $arr[$a_i++];
        } else {
            $temp[] = $arr[$b_i++];
        }
    }
    //判断 数组A内的元素是否都用完了,没有的话将其全部插入到C数组内:
    while($a_i <= $center) {
        $temp[] = $arr[$a_i++];
    }
    //判断 数组B内的元素是否都用完了,没有的话将其全部插入到C数组内:
    while($b_i <= $right) {
        $temp[] = $arr[$b_i++];
    }
 
    //将$arrC内排序好的部分,写入到$arr内:
    for($i=0, $len=count($temp); $i<$len; $i++) {
        $arr[$left+$i] = $temp[$i];
    }
 
}
 
 
//do some test:
$arr = array(4, 7, 6, 3, 9, 5, 8);
mergeSort($arr);
print_r($arr);

 

 

Binary search

Prerequisite: The search array must be ordered

1) Obtain and record the upper limit, lower limit, and middle subscript of the array ;

2) Compare the intermediate subscript value with the target value , if:

    ①The target value <the middle value, the upper limit is reduced by 1, and the corresponding middle subscript is changed ;

    ②Target value> middle value, add 1 to the lower limit, and change the corresponding middle subscript ;

    ③Target value = intermediate value, matching is successful

/**
     * 二分查找法
     * 使用前提是有序数组
     */
    public function binarySearch($value = 22, $arr = array(3, 4, 6, 7, 9, 16, 22) ){
        $low = 0;    //数组下限下标
        $high = count($arr)-1;    //数组上限下标

        // 注意凡是使用到while的时候,一定要防备无限循环的时候,注意终止循环的判断。
        while($low <= $high){
            //获取中间比较的中间下标(强制整形)
            $middle = intval(($low + $high)/2);

            if($value < $arr[$middle]){    //目标值 < 中间值 ,上限减1
                $high = $middle - 1;
            }elseif ($value > $arr[$middle]){    //目标值 > 中间值 ,下限加1
                $low = $middle + 1;
            }else{
                return $middle;     //目标值 = 中间值,匹配成功返回下标值
            }
        }

        return -1;
    }

 

Guess you like

Origin blog.csdn.net/weixin_43452467/article/details/113941069