挿入ソート
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;
}