PHP4の主要なソートアルゴリズムとバイナリ検索

挿入ソート

   1.最初の要素から始めて、要素はソートされたと見なすことができます
   2.次の要素を取り出し、ソートされた要素のシーケンスで後ろから前比較します
   3.要素(ソート済み)が新しい要素よりも大きい場合要素、それ要素は次の位置に移動します

/**
     * 插入排序
     */
    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;
    }

 

単純な選択ソート

思想:

1)n回ループし、毎回要素交換の最小要素見つけます 。

/**
     * 简单排序
     * 循环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;
    }

 

バブルソート

アイデア:

1)最初のループループの数を制御します。配列の長さはn-1回です(最悪の結果は、結果が得られる前にn-1回比較することです)

2)2番目のループは配列の各要素を比較し、次の要素は前の要素よりも小さく、位置交換されます一時変数$ tmpが必要です
 

 

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;
}

 

クイックソート

アイデア: 
1)参照要素(通常は最初の要素または最後の要素 )を選択します
。2)並べ替えによって並べ替えるレコードを2つの独立した配列に分割します。ここで、小さい配列レコードの要素値はすべて、参照要素値が小さい場合、大きな配列に記録される要素値は参照値よりも大きくなります。 
3)次に、同じメソッドで、シーケンス全体が順序付けられるまで、大小の配列を再帰的に並べ替えます。 
4)最後に、小さな配列、基本要素、および大きな配列をマージします。 

 /**
     * 快速排序
     */
    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);
    }

 

マージソート

マージ(マージ)ソート方法は、2つ(またはそれ以上)の順序付きリストを新しい順序付きリストにマージすることです。つまり、ソートされるシーケンスをいくつかの順序付きサブシーケンスに分割してから、順序付きサブシーケンスを分割します。マージは全体的な順序付きシーケンスになります。

/**
* 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);

 

 

二分探索

前提条件:検索配列を並べ替える必要があります

1)配列の上限、下限、および中間添え字を取得して記録します。

2)次の場合中間添え字値をターゲット値と比較します

    ①目標値<中間値、上限を1減らし、対応する中間添え字を変更します。

    ②目標値>中間値、下限に1を加算し、対応する中間添え字を変更します

    ③目標値=中間値、マッチングは成功

/**
     * 二分查找法
     * 使用前提是有序数组
     */
    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;
    }

 

おすすめ

転載: blog.csdn.net/weixin_43452467/article/details/113941069