十大排序算法(PHP版)

目录

1.快速排序

2.插入排序

3.希尔排序

4.归并排序

5.堆排序

6.冒泡排序

7.计数排序

8.基数排序

9.桶排序

10.选择排序


1.快速排序

tip:从1开始每个数和arr[0]比较,分别放进左右数组,递归,合并

代码:

function quicksort($arr){

        if(count($arr) <=1){

            return $arr;

        }

        $larr = [];

        $rarr = [];

        for($i=1;$i<count($arr);$i++){

            if($arr[$i] <= $arr[0]){

                $larr[] = $arr[$i];

            }else{

                $rarr[] = $arr[$i];

            }

        }

        $left = quicksort($larr);

        $right = quicksort($rarr);

        return array_merge($left,array($arr[0]),$right);

    }

2.插入排序

tip:从数组第二位开始遍历,和前面的数比较,符合就互换位置,直到遍历所有数

代码:

function insert_sort($arr){
     
    for($i=1;$i<count($arr);$i++){
        
        //待插入的值
        $temp = $arr[$i];
        
        //待比较的值
        $j = $i-1;
        while($j>=0&&$temp>$arr[$j])
        {
            $arr[$j+1] = $arr[$j];
            $arr[$j] = $temp;
            $j--;
        }
        $arr[$j+1] = $temp;
    }
    
    return $arr;
 }

3.希尔排序

tip:带基数的插入排序

代码:

function shellsort($arr){
    
    //初始化增量
    $increment = count($arr);
    
    while($increment > 1)
    {
        $increment = intval($increment/3) + 1;
        
        for($i=$increment;$i<count($arr);$i++){
            
            //待插入值
            $temp = $arr[$i];
            
            //待比较位置
            $j = $i - $increment;
            
            //降序排列
            while($j>=0&&$temp>$arr[$j])
            {
                $arr[$j+$increment] = $arr[$j];
                $arr[$j] = $temp;
                $j = $j-$increment;
            }
            
            $arr[$j+$increment] = $temp;
        }
    }
    
    return $arr;
}

4.归并排序

tip:把数组切割,直到不可分割,排序单个小数组,然后合并,递归执行

代码:

function merge_sort(&$arr){
    
    $count = count($arr);
    
    if($count <= 1){
        return $arr;
    }
    
    $mid = intval($count/2);
    
    $left = array_slice($arr, 0,$mid);
    $right = array_slice($arr, $mid);
    
    merge_sort($left);
    merge_sort($right);
    
    $merge=[];
    while(count($left)&&count($right)){
        $merge[] = $left[0]<$right[0] ? array_shift($left):array_shift($right);
    }
    $arr = array_merge($merge,$left,$right);
    
//    var_dump($arr);
}

5.堆排序

tip:以最后一个父节点为起始节点,比较子节点,把最小值或最大值移动到父节点,遍历所有父节点后
    //最小值或最大值移动到根节点,把根节点和尾节点交换,数组长度减一继续遍历

代码:

function heep_sort($arr)
 {
     //获取数组的长度
     $arrsize = count($arr);
    
    while($arrsize > 0)
    {
        //遍历每个节点,和子节点比较得到最小值
        for($i = intval($arrsize/2)-1;$i>=0;$i--){
            
            //起初认定当前节点最小
            $min = $i;
            
            //如果存在左节点
            if($i*2+1 < $arrsize){
                //比较和左节点的大小,如果左节点的值更小,那么进行交换
                if($arr[$i] > $arr[$i*2+1]){
                    $temp = $arr[$i];
                    $arr[$i] = $arr[$i*2+1];
                    $arr[$i*2+1] = $temp;
                }
            }
            
            //如果存在又节点
            if($i*2+2 < $arrsize){
                //比较和右节点的大小,如果右节点的值更小,那么进行交换
                if($arr[$i] > $arr[$i*2+2]){
                    $temp = $arr[$i];
                    $arr[$i] = $arr[$i*2+2];
                    $arr[$i*2+2] = $temp;
                }
            }
            
            //执行完一次遍历,跳到下一个非叶子节点
            
        }
        
        //成功找到第一个最小值,使数组长度减一
        //首尾交换,保存最小值
        $temp = $arr[0];
        $arr[0] = $arr[$arrsize-1];
        $arr[$arrsize-1] = $temp;
        $arrsize--;
        
    }
    
    return $arr;
 }

6.冒泡排序

tip:这个就不用说了,很简单

代码:

function maopao($arr){
        
        $count=count($arr);
        
        for($i=0;$i<$count;$i++){
            for($j=0;$j<$count-$i-1;$j++){
                if($arr[$j]<$arr[$j+1]){
                    $temp = $arr[$j];
                    $arr[$j] = $arr[$j+1];
                    $arr[$j+1] = $temp;
                }
            }
        }
        
        var_dump($arr);
    }

7.计数排序

tip:时间复杂度O(n+k),n为排序的数的个数,k为要排序的数的最大值,消耗空间来达到快捷,空间换时间,
    //计算数组的最大和最小值,创建一个键从min到max的数组,计数排序数组的每个值的个数,然后向一个新数组填充入栈

步骤:

    找出待排序的数组中最大和最小的元素

    统计数组中每个值为i的元素出现的次数,存入数组C的第i项
    
    对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加)
    
    反向填充目标数组:将每个元素i放在新数组的第C[i]项,每放一个元素就将C[i]减去1

代码:

function countsort($arr){
     
    $count = count($arr);
    $carr = [];
    $min = $arr[0];
    $max = $arr[0];
     //找最大值和最小值
     for($i=1;$i<$count;$i++){
        
         if($arr[$i]<$min){
             $min = $arr[$i];
         }
        if($arr[$i]>$max){
            $max = $arr[$i];
        } 
     }
    
    for($i=$min;$i<=$max;$i++){
        $carr[$i] = 0;
    }
    
    for($i=1;$i<$count;$i++){
         
         $carr[$arr[$i]]++;
     }
    
    $newarr = [];
    
    for($i=$max;$i>=$min;$i--){
        
        while($carr[$i]>0)
        {
            $newarr[]=$i;
            $carr[$i]--;
        }
    }
    
    var_dump($newarr);
 }

8.基数排序

代码:

//默认降序
function radixSort($arr, $desc=true)
{
	if (count($arr) <= 1) {
		return $arr;
	}
	
	$max = $arr[0];
	for($i=1;$i<count($arr);$i++)
	{
		if ($arr[$i] > $max){
			$max = $arr[$i];
		}
	}
	
	$n = 0;//记录最大数的位数
	while($max > 1){
		$max = $max/10;
		$n++;
	}
	
	
	for($j=1;$j<=$n;$j++){
		$tmp_arr = [];
		
		for($k=0;$k<count($arr);$k++){
			$r = pow(10,$j-1);
			$num = $arr[$k] > $r ? intval($arr[$k]/$r)%10 : 0;
			$tmp_arr[$num][] = $arr[$k];
		}
		
		$arr=[];
		if ($desc) {
			for($m=9;$m>=0;$m--)
			{
				if (!empty($tmp_arr[$m])){
					for($p=0;$p<count($tmp_arr[$m]);$p++){
						$arr[] = $tmp_arr[$m][$p];
					}
				}
			}
		} else {
			for($m=0;$m<=9;$m++)
			{
				if (!empty($tmp_arr[$m])){
					for($p=0;$p<count($tmp_arr[$m]);$p++){
						$arr[] = $tmp_arr[$m][$p];
					}
				}
			}
		}
		
	}
	return $arr;
}

9.桶排序

代码:

function bucketSort($arr, $bucketSize = 5)
{
    if (count($arr) === 0) {
      return $arr;
    }

    $minValue = $arr[0];
    $maxValue = $arr[0];
    for ($i = 1; $i < count($arr); $i++) {
      if ($arr[$i] < $minValue) {
          $minValue = $arr[$i];
      } else if ($arr[$i] > $maxValue) {
          $maxValue = $arr[$i];
      }
    }

    $bucketCount = floor(($maxValue - $minValue) / $bucketSize) + 1;
    $buckets = array();
    for ($i = 0; $i < $bucketCount; $i++) {
        $buckets[$i] = [];
    }

    for ($i = 0; $i < count($arr); $i++) {
        $buckets[floor(($arr[$i] - $minValue) / $bucketSize)][] = $arr[$i];
    }

    $arr = array();
    for ($i = 0; $i < count($buckets); $i++) {
        $bucketTmp = $buckets[$i];
        sort($bucketTmp);
        for ($j = 0; $j < count($bucketTmp); $j++) {
            $arr[] = $bucketTmp[$j];
        }
    }

    return $arr;
}

10.选择排序

tip:思路分析:在要排序的一组数中,选出最小的一个数与第一个位置的数交换。
            然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较为止。

代码:

function select_sort($arr){
		
		$count=count($arr);
		
		//循环次数
		for($i=0;$i<$count-1;$i++){
			
			//假设最小值的位置
			$p = $i;
			
			for($j=$i+1;$j<$count;$j++){
				
				if($arr[$p]>$arr[$j]){
					$p = $j;
				}
			}
			
			if($p!=$i){
				//说明最小值发生变化
				$temp = $arr[$p];
				$arr[$p] = $arr[$i];
				$arr[$i] = $temp;
			}
		}
		
		var_dump($arr);
		
	}

速度测试:

//测试    5000个0-999的随机数
//基数排序        0ms
//堆排序           8ms
//希尔排序        22ms    
//插入排序        5ms        
//归并排序        0-1ms    20000个数在2ms内    分割
//快速排序        0ms        20000个数在1ms内    递归
//计数排序        0ms        1000000个数在3ms内        快但消耗空间
//冒泡排序        12ms    最慢

//选择排序        5ms

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

end for time

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值