• 用PHP实现的快速排序算法(支持记录原始数组下标)


    代码如下

    <?php
    /**
     * 快速排序
     */
    define("MAX_LENGTH_INSERT_SORT", 7); class QuickSort { /** * 交换数组i和j的值 */ function swap(&$data=array(), $i, $j) { $temp = $data[$i]; $data[$i] = $data[$j]; $data[$j] = $temp; } /** * 交换数组data中子表的记录,是枢轴记录到位,并返回其所在位置 * 左边记录都比枢轴小,右边记录都比枢轴大 * @param array $data 待排序数组 * @param int $low 底端下标 * @param int $high 顶端下标 * @return low 枢轴下标位置 */ function PartitionAsc(&$data=array(), $low=0, $high=0) { $pivotkey=0; //计算数组中间元素的下标 $m = $low+($high-$low)/2; //交换左端和右端数据,保证左端较小 if($data[$low]>$data[$high]) { $this->swap($data, $low, $high); } //交换中间和右端数据,保证中间较小 if($data[$m]>$data[$high]) { $this->swap($data, $high, $m); } //获取中间数据,并将中间数据交换到左边 if($data[$m]>$data[$low]) { $this->swap($data, $m, $low); } //用子表的第一个记录作枢轴记录 $pivotkey = $data[$low]; //将枢轴关键字备份到L->r[0] $data[0] = $pivotkey; //从表的两端交替地向中间扫描 while($low<$high) { while ($low<$high && $data[$high]>=$pivotkey) { $high--; } $data[$low] = $data[$high]; while ($low<$high && $data[$low]<=$pivotkey) { $low++; } $data[$high] = $data[$low]; } $data[$high] = $data[0]; return $low; } /** * 交换数组data中子表的记录,是枢轴记录到位,并返回其所在位置 * 左边记录都比枢轴大,右边记录都比枢轴小 * @param array $data 待排序数组 * @param int $low 底端下标 * @param int $high 顶端下标 * @return low 枢轴下标位置 */ function PartitionDesc(&$data=array(), $low=0, $high=0) { $pivotkey=0; //计算数组中间元素的下标 $m = $low+($high-$low)/2; //交换左端和右端数据,保证左端较小 if($data[$low][0]<$data[$high][0]) { $this->swap($data, $low, $high); } //交换中间和右端数据,保证中间较小 if($data[$m][0]<$data[$high][0]) { $this->swap($data, $high, $m); } //获取中间数据,并将中间数据交换到左边 if($data[$m][0]<$data[$low][0]) { $this->swap($data, $m, $low); } //用子表的第一个记录作枢轴记录 $pivotkey = $data[$low]; //将枢轴关键字备份到L->r[0] $data[0] = $pivotkey; //从表的两端交替地向中间扫描 while($low<$high) { while ($low<$high && $data[$high][0]<=$pivotkey[0]) { $high--; } $data[$low] = $data[$high]; while ($low<$high && $data[$low][0]>=$pivotkey[0]) { $low++; } $data[$high] = $data[$low]; } $data[$high] = $data[0]; return $low; } /** * 快速排序(升序) * @param array $data 待排序数组 * @param int $low 底端下标 * @param int $high 顶端下标 * @return void */ function QsortAsc(&$data=array(), $low=0, $high=0) { $pivot=0; //当high-low大于常数时用快捷排序 if(($high-$low)>MAX_LENGTH_INSERT_SORT) { while($low<$high) { //将data一分为二,算出枢轴值pivot $pivot = $this->PartitionAsc($data, $low, $high); //对底子表递归排序 $this->QsortAsc($data, $low, $pivot-1); //尾递归 $low = $pivot+1; } } else { //当high-low小于等于常数时用直接插入排序 $this->InsertSortAsc($data, $low, $high); } } /** * 快速排序(降序) * @param array $data 待排序数组 * @param int $low 底端下标 * @param int $high 顶端下标 * @return void */ function QsortDesc(&$data=array(), $low=0, $high=0) { $pivot=0; //当high-low大于常数时用快捷排序 if(($high-$low)>MAX_LENGTH_INSERT_SORT) { while($low<$high) { //将data一分为二,算出枢轴值pivot $pivot = $this->PartitionDesc($data, $low, $high); //对底子表递归排序 $this->QsortDesc($data, $low, $pivot-1); //尾递归 $low = $pivot+1; } } else { //当high-low小于等于常数时用直接插入排序 $this->InsertSortDesc($data, $low, $high); } } /** * 插入排序(升序) */ function InsertSortAsc(&$data=array(), $low=0, $high=0) { $i=$j=0; if(0 == $high) { $length=count($data)-1; } else { $length=$high; } for($i=$low+1;$i<=$length;$i++) { if($data[$i][0]<$data[$i-1][0]) { $data[0]=$data[$i]; for ($j=$i-1; $data[$j][0]>$data[0][0]; $j--) { if($j<$low) break; $data[$j+1]=$data[$j]; } $data[$j+1]=$data[0]; } } } /** * 插入排序(降序) */ function InsertSortDesc(&$data=array(), $low=0, $high=0) { $i=$j=0; if(0 == $high) { $length=count($data)-1; } else { $length=$high; } for($i=$low+1;$i<=$length;$i++) { if($data[$i][0]>$data[$i-1][0]) { $data[0]=$data[$i]; for ($j=$i-1; $data[$j][0]<$data[0][0]; $j--) { if($j<$low) break; $data[$j+1]=$data[$j]; } $data[$j+1]=$data[0]; } } } /** * 快速排序 * @param array $data 待排序数组 * @param int $type 1升序 2降序 默认升序 * @return void */ function Sort($data=array(), $type=1) { $length = count($data)-1; if(1==$type) { $this->QsortAsc($data, 1, $length); } else if(2==$type) { $this->QsortDesc($data, 1, $length); } else { $this->QsortAsc($data, 1, $length); } return $data; } } /********************************************************/ //测试10万数组排序 //测试数组:array(array(排序数据, 原始数组下标),......) $data = array(array(0,0)); $max_len = 100000; for($i=1; $i<$max_len; $i++) { $data[$i] = array(rand(1,$max_len),$i); } $qs = new QuickSort(); //1升序, 2降序 $qs->Sort($data,2); $qs->Sort($data,1);

    测试结果:10万条数据耗时2.7秒

  • 相关阅读:
    redis性能优化——生产中实际遇到的问题排查总结
    Redis优化经验
    Python 发送 email 的两种方式
    封装简单的equery
    Mobiscroll的介绍【一款兼容PC和移动设备的滑动插件】
    css3毛玻璃模糊效果
    环形进度条的实现方法总结和动态时钟绘制(CSS3、SVG、Canvas)
    CSS实现圆角,三角,五角星,五边形,爱心,12角星,8角星,圆,椭圆,圆圈,八卦
    盘点8种CSS实现垂直居中水平居中的绝对定位居中技术
    CSS 去掉inline-block间隙的几种方法
  • 原文地址:https://www.cnblogs.com/phpfans/p/4104425.html
Copyright © 2020-2023  润新知