[一天一个排序算法] - 冒泡算法最优 & 选择排序
每天一点点 , 进步还是非常大的,虽然我是学了又忘记,但是还是得加油啊,就当吧博客当作笔记了,今天来学习一些排序算法中最基本的算法,冒泡排序
首先,冒泡排序, 冒泡冒泡,就是一个个的冒出小泡呗。

首先,亮出最基本的 冒泡排序出来
 function dubble_sort( &$arr ) : void {
     $len = count($arr);
 
     for ($i=0; $i <$len ; $i++) { 
         for ($j=0; $j <$len-1 ; $j++) { 
             if( $arr[$j+1] < $arr[$j] ) {
                 list($arr[$j] , $arr[$j+1]) = [ $arr[$j+1] , $arr[$j] ];
             }
         }
     }
 
     $arr = implode('-',$arr) . '<br/>';
 }
双层循环,给每个元素进行遍历,在子循环中交换元素
这里采用了 list 交换元素, 至于为什么,自己理解哦,我们这里主要来学习,最优算法的
首先优化一
function dubble_sort_s( &$arr ) : void { $len = count($arr); for ($i=0; $i <$len ; $i++) { $swapped = false; for ($j=0; $j <$len-1 ; $j++) { if( $arr[$j+1] < $arr[$j] ) { list($arr[$j] , $arr[$j+1]) = [ $arr[$j+1] , $arr[$j] ]; $swapped = true; } } if( !$swapped ) break; } $arr = implode('-',$arr); }
我们给每个子循环体添加了一个 参数 $swapped , 仔细想一想,当子循环体第一次循环的时候
例: 2 4 8 1 9 
    2 4 1 8 9 true  (发生了交换)
    
    2 1 4 8 9 true  (发生了交换)
    
    1 2 4 8 9 true  (发生了交换)
    
    1 2 4 8 9 false 
这里只执行了 父循环体三次, 就完成了排序,试想一下,这不是消耗了资源吗
所以,我没可以给他添加变量,检查是否发生了交换,如果没有则退出循环
优化二
function dubble_sort_x( &$arr ) : void { $len = count($arr);
for ($i=0; $i < $len ; $i++) { $swapped = false; for ($j=0; $j <$len-$i-1 ; $j++) { # $j 循环体改变了 if( $arr[$j+1] < $arr[$j] ) { list($arr[$j] , $arr[$j+1]) = [ $arr[$j+1] , $arr[$j] ]; $swapped = true; } } if( !$swapped ) break; } $arr = implode('-',$arr);}
我们修改了子循环体的循环次数,为什么呢,如下
例如: 2 4 1 8 9 2
     2 1 4 8 2 9  # 1
      
     2 1 4 2 8 9  # 2 
     
     1 2 2 4 8 9  # 3
仔细瞧瞧, 你会发现 ,每次循环绝对会把最后一个参数给比较掉,前面的参数较来说不确定
所以在循环中,我们如果不添加如上,每次循环都会对尾部的元素多进行循环一次,这是无谓的消耗
优化三
function dubble_sort_z( &$arr ) : void { $len = count($arr); $swapped = false; $bound = count($arr-1); for ($i=0; $i <$len ; $i++) { for ($j=0; $j <$bound ; $j++) { if( $arr[$j+1] < $arr[$j] ) { list($arr[$j] , $arr[$j+1]) = [ $arr[$j+1] , $arr[$j] ]; $swapped = true; $newBound = $j; } } if( !$swapped ) break; } $arr = implode('-',$arr); }
这个和优化二的差不多,尝试理解一下,$newBound 代表当前已经排序的最终位置,后面的数项可以不需要进行排序了,直接精确定位,下次子循环的时候将不在进行后续的循环
选择排序
选择排序,即是将最小的数前置,将所有的数字与之对比,然后进行交换
function selectionSort( &$arr ) {
    $len = count( $arr ) ;
    for ( $i=0; $i<$len ; $i++ ) {
        $min = $arr[$i];
        # 遍历,找出比第一个小的值出来
        for ( $j=$i+1; $j<$len; $j++ ) {
            if( $arr[$j] < $min ) {
                $min = $arr[$j];
                $index = $j;
            }
        }
        # 已经找出了最小的,再进行交换
        list( $arr[$i] , $arr[$index]) = [$min , $arr[$i]];
    }
    $arr = implode('-',$arr);
}
例: 2 7 6 4 3 5 
    
    2 3 6 4 7 5
    
    2 3 4 6 7 5 
    
    2 3 4 5 7 6 
    
    2 3 4 5 6 7		
			本文由 邓尘锋 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: May 4, 2019 at 11:38 am