橘子味的心
php实现7种常见排序
php实现7种常见排序
发布于:

class test{  
 public function main()
    {

        $data = $this->createData();
        $this->bubbleSort($data);
        $this->selectSort($data);
        $this->insertSort($data);
        $this->shellSort($data);
        $this->mergeSort($data);
        $this->heapSort($data);
        $this->fastSort($data);
    }

    public function createData()
    {
        $firtime = microtime();
        $data = [];
        for($i = 0; $i < 1000000;){
            $val = ceil(rand(1,1000000));
            if(!in_array($val, $data)){
                $data[] = $val;
                $i++;
            }
        }
        $sectime = microtime();
        $this->getTimeLimit($firtime, $sectime);
        return $data;
    }

    //归并排序开始
    public function mergeSort($data)
    {
        $firtime = microtime();
        $res = $this->mergeSortMain($data, 0, count($data)-1);
        $sectime = microtime();
        $this->getTimeLimit($firtime, $sectime);
    }

    public function mergeSortMain(&$data, $from, $to){
        if($from == $to){
            return [$data[$to]];
        }
        $middle = floor(($to + $from)/2);
        $left = $this->mergeSortMain($data, $from, $middle);
        $right = $this->mergeSortMain($data, $middle+1, $to);
        $res = $this->sortTwoSortArr($left, $right);
        return $res;
    }

    public function sortTwoSortArr($arrA, $arrB){
        $res = [];
        $index = 0;
        $indexA = 0;
        $indexB = 0;
        while (count($arrA)&&count($arrB)) {
            if ($arrA[$indexA] < $arrB[$indexB]) {
                $res[$index++] =  $arrA[$indexA];
                unset($arrA[$indexA++]);
            } else {
                $res[$index++] =  $arrB[$indexB];
                unset($arrB[$indexB++]);
            }
        }
        if (count($arrA)) {
            while (count($arrA)) {
                $res[$index++] =  $arrA[$indexA];
                unset($arrA[$indexA++]);
            }
        } elseif (count($arrB)){
            while (count($arrB)) {
                $res[$index++] =  $arrB[$indexB];
                unset($arrB[$indexB++]);
            }
        }
        return $res;
    }
    //归并排序结束

    //快速排序开始
    public function fastSort($data)
    {
        $firtime = microtime();
        $this->fastSortMain(0, count($data) - 1, $data);
        $sectime = microtime();
        $this->getTimeLimit($firtime, $sectime);
    }

    public function fastSortMain($start, $end, &$data){
        if ($start >= $end) {
            return;
        }
        $middle = $this->fastSortSwap($start, $end, $data);
        $this->fastSortMain($start, $middle-1, $data);
        $this->fastSortMain($middle+1, $end, $data);
    }


    //这个方法的作用是把 $data从start到end之间的部分 分成大于某值或者小于某值两部分,并且返回某值的位置
    public function fastSortSwap($start, $end, &$data){
        $flag = $data[$end];
        $resust_key = $start;
        for ($i=$start; $i < $end; $i++) { 
            if ($data[$i] > $flag) {
                continue;
            } else {
                $temp = $data[$i];
                $data[$i] = $data[$resust_key];
                $data[$resust_key++] = $temp;
            }
        }
        $data[$end] = $data[$resust_key];
        $data[$resust_key] = $flag;
        return $resust_key;
    }
    //快速排序结束
    
    //选择排序开始
    public function selectSort($data)
    {
        $firtime = microtime();
        for ($i=0; $i <count($data) ; $i++) {
            $minval = $data[$i];
            $minkey = $i;
            for ($j=$i; $j < count($data); $j++) { 
                if($data[$j]<$minval){
                    $minval = $data[$j];
                    $minkey = $j;
                }
            }
            $temp = $data[$i];
            $data[$i] = $minval;
            $data[$minkey] = $temp;
        }
        $sectime = microtime();
        $this->getTimeLimit($firtime, $sectime);
    }
    //选择排序结束
    
    //希尔排序开始
    public function shellSort($data)
    {
        $firtime = microtime();
        $jump = floor(count($data)/2);
        while($jump >= 1){
            for ($i = 0; $i < $jump; $i++) {
                for ($j = $i + $jump; $j < count($data);) {
                    $temp = $data[$j];
                    $k = $j - $jump;
                    while ($k >= 0&&$data[$k] > $temp) {
                        $data[$k + $jump] = $data[$k];
                        $k = $k - $jump;
                    }
                    $data[$k + $jump] = $temp;
                    $j += $jump;
                }
            }
            $jump = floor($jump/2);
        }
        $sectime = microtime();
        $this->getTimeLimit($firtime, $sectime);
    }
    //希尔排序结束
    
    //冒泡排序开始
    public function bubbleSort($data)
    {
        $firtime = microtime();
        for ($i = count($data)-1; $i > 0; $i--) {
            $flag = true;
            for ($j=0; $j < $i; $j++) { 
                if($data[$j] > $data[$j+1]){
                    $temp = $data[$j];
                    $data[$j] = $data[$j+1];
                    $data[$j+1] = $temp;
                    $flag = false;
                }
            }
            if($flag){
                break;
            }
        }
        $sectime = microtime();
        $this->getTimeLimit($firtime, $sectime);
    }
    //冒泡排序结束
    
    //插入排序开始
    public function insertSort($data){
        $firtime = microtime();
        for ($i = 1; $i < count($data); $i++) {
            $temp = $data[$i];
            $j = $i - 1;
            while ($j > 0&&$data[$j] > $temp) {
                $data[$j+1] = $data[$j];
                $j--;
            }
            $data[$j+1] = $temp;
        }
        $sectime = microtime();
        $this->getTimeLimit($firtime, $sectime);
    }
    //插入排序结束
    
    //堆排序开始

    public function heapSort($data){
        $firtime = microtime();
        $this->initHeap($data);
        $n = count($data);
        for ($i = $n - 1; $i > 0; $i--) { 
            $this->swap($data, 0, $i);
            $this->down($data, 0, $i - 1);
        }
        $sectime = microtime();
        $this->getTimeLimit($firtime, $sectime);
    }

    public function initHeap(&$data){
        $n = count($data);
        for ($i = $n/2-1; $i >= 0; $i--) { 
            $this->down($data, $i, $n-1);
        }
    }

    public function swap(&$data, $i, $j){
        $n = count($data);
        if ($i < 0||$j < 0||$i > $n||$j > $n) {
            return;
        } else {
            $temp = $data[$i];
            $data[$i] = $data[$j];
            $data[$j] = $temp;
        }
    }

    public function down(&$data, $head, $tail){
        $left_child = $head * 2 + 1;
        $right_child = $left_child + 1;
        $next_head = $left_child;
        $head_val = $data[$head];
        while ($left_child <= $tail) {
            if ($right_child <= $tail&&$data[$right_child] > $data[$left_child]) {
                $next_head = $right_child;
            }
            if ($data[$next_head] > $head_val) {//无论何时都只和最上面的那个值比较
                $data[$head] = $data[$next_head];
            } else {
                break;
            }
            $head = $next_head;
            $left_child = $head * 2 + 1;
            $right_child = $left_child + 1;
            $next_head = $left_child;
        }
        $data[$head] = $head_val;
    }
    //堆排序结束
    
    //获取花费时间开始
    public function getTimeLimit($a, $b){
        list($seconds1, $msecond1) = explode(' ', $a);
        list($seconds2, $msecond2) = explode(' ', $b);
        var_dump(($seconds2 - $seconds1)+($msecond2 - $msecond1));
    }
    //获取话费时间结束
}

最后发现7种排序的效率从低到高依次为

冒泡排序

选择排序

插入排序

希尔排序

归并排序

堆排序

快速排序

将数据量增加到1000w,也没有看到堆排序的优势,还是快速排序效率最高,留坑待填//todo


阅读 0

分类

    热门排行