算法复习---排序

稳定的排序:排序之后,源数据中相同的数据相对位置不会发生改变
不稳定的排序:反之。

冒泡

<?php
$test = array(12,10,1,5,10);
foreach($test as  $val){
    echo $val . ",";
}
for($i=0;$i<count($test);$i++){
    for($j=0;$j<count($test)-$i-1;$j++){
        if($test[$j]>$test[$j+1]){
            $tmp=$test[$j];
            $test[$j]=$test[$j+1];
            $test[$j+1]=$tmp;
        }   
    }   
}

二分查找

bin($test222, 58, 0, count($test222)-1);

function bin($data, $num, $left, $right){
    if($left > $right){
        echo "无次数";
        return;
    }

    $mid = round(($left + $right)/2);
    if($data[$mid] == $num){
        echo $mid  . " -- " . $num;
        return;
    }else if ($data[$mid] > $num){
        bin($data, $num, $left, $mid-1);
    }else if ($data[$mid] < $num){
        bin($data, $num, $mid+1, $right);
    }


}

快排

quicksort($test222, 0, count($test222)-1);
function quicksort(&$data, $left, $right){
    if($left < $right){
        $dp = onesort($data, $left, $right);
        quicksort($data,$left, $dp-1);
        quicksort($data,$dp+1, $right);
    }   
}
function onesort(&$data, $left, $right){
    $tmp = $data[$left];
    while($left < $right){
        while($left<$right&&$tmp<=$data[$right])
            $right--;
        if($left < $right)
            $data[$left++] = $data[$right];
        while($left<$right && $tmp>=$data[$left])
            $left++;
        if($left < $right)
            $data[$right--] = $data[$left];
    }
    $data[$left] = $tmp;
    return $left;
}

优化方案:
1。当数据量小的时候,采用插入排序效率更高
2。单次好序的数据,如果有相同数据,相同的数据进行聚合,减少相同数据的排序次数
3。三数取中,开头,结尾,中间的数,三个数去中间大小的数据作为开始值。

堆排序

堆排序参考的博客

<?php
$data = array(2,6,3,66,55,12,336,55,44,78,5,3,0,15,56,4);
//先将数组各个节点从下至上进行堆排序,
for($i=floor(count($data)/2-1); $i>=0; $i--){
    duisort($data, $i, count($data)-1);    
}

//排好序的数据,堆顶元素与最后一位进行置换,然后对剩余元素继续堆排序
for($i=count($data)-1;$i>=0;$i--){
    swap($data, 0, $i);
    duisort($data,0, $i);    
}

foreach($data as $val){
    echo $val . ",";    
}

function duisort(&$data, $index, $size){
    $head = $index;

    $left = 2 * $index + 1;
    $right = 2 * $index + 2;

    if($left < $size && $data[$head] < $data[$left]){
        $head = $left;    
    }   

    if($right < $size && $data[$head] < $data[$right]){
        $head = $right;    
    }   

    if($head != $index){
        swap($data, $head, $index);
        duisort($data, $head, $size);
    }   
}

function swap(&$data, $head, $index){
    $tmp = $data[$index];
    $data[$index] = $data[$head];
    $data[$head] = $tmp;
}

插入

<?php

$data=array(2,5,6,3,1,0);
insert($data);
foreach($data as $val){
    echo $val . ",";
}

function insert(&$data){
    for($i=1; $i<count($data); $i++){
        $tmp = $data[$i];
        $key = $i-1;

        while($key>=0 && $tmp<$data[$key]){
            $data[$key+1] = $data[$key];
            $key--;
        }   
        if($key+1 != $i){
            $data[$key+1] = $tmp;
        }   
    }   
}

希尔

有步长的插入排序

<?php

$data = array(5,3,4,8,9,0,10,2);

shell($data);

foreach($data as $val){
    echo $val . ",";
}

function shell(&$data){
    $h=1;
    $size = count($data);
    while($h<floor($size/3)){
        $h = 3*$h +1; 
    }   
    while($h>=1){
        echo "步长为:" . $h . "\n";
        for($i=$h; $i<$size; $i++){
            for($j=$i;$j>=$h&&($data[$j]<$data[$j-$h]);$j-=$h){
                $tmp=$data[$j];
                $data[$j] = $data[$j-$h];
                $data[$j-$h] = $tmp;
            }   
        }   
        $h = floor($h/3);
    }   

}

归并

<?php
$a = array(12,1,3,5,7,9,4);
$c =array();

dsort($a, 0, count($a)-1, $c);

foreach($a as $val){
    echo $val . ",";
}

function dsort(&$a,$left, $right, $c){

    if($left < $right){
        $mid = floor(($left+$right)/2);
        dsort($a,$left, $mid, $c);
        dsort($a,$mid+1, $right,  $c);
        mersort($a, $left, $mid, $right, $c);
    }
}

function mersort(&$a, $left, $mid, $right, $c){
    $i = $left;
    $j = $mid+1;
    $k = 0;

    while($i<=$mid && $j<=$right){
        if($a[$i] <= $a[$j]){
            $c[$k++] = $a[$i++];
        }else{
            $c[$k++] = $a[$j++];
        }
    }

    while($i<=$mid){
        $c[$k++] = $a[$i++];
    }

    while($j<=$right){
        $c[$k++] = $a[$j++];
    }

    for($i=0; $i<$k; $i++){
        $a[$left+$i] = $c[$i];
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值