JS及PHP代码编写八大排序算法


Posted in Javascript onJuly 12, 2016

从学习数据结构开始就接触各种算法基础,但是自从应付完考试之后就再也没有练习过,当在开发的时候也是什么时候使用什么时候去查一下,现在在学习JavaScript,趁这个时间再把各种基础算法整理一遍,分别以JS和PHP语法的方式编写代码。
1.冒泡排序
原理:临近的数字两两进行比较,按照从小到大或者从大到小的顺序进行交换,这样一趟过去后,最大或最小的数字被交换到了最后一位,然后再从头开始进行两两比较交换,直到倒数第二位时结束
时间复杂度:平均情况:O(n2)  最好情况:O(n) 最坏情况:O(n2)
空间复杂度:O(1)
稳定性:稳定

 

//JavaScript语法
 var array = [23,0,32,45,56,75,43,0,34];

 for(var i = 0; i < array.length; i++)
 {
  var isSort = true;
  for(var j = 0; j < array.length - 1 - i; j++)
  {
  if(array[j] > array[j+1])
  {
   isSort = false;
   var temp = array[j];
   array[j] = array[j + 1];
   array[j + 1] = temp;
  }
  }
  if(isSort)
  {
  break;
  }
 }
 console.log(array);
<?php
 $array = [23,0,32,45,56,75,43,0,34];

 for($i = 0; $i < count($array); $i++)
 {
  $isSort = true;
  for($j = 0; $j < count($array) - 1; $j++)
  {
  if($array[$j] > $array[$j+1])
  {
   $isSort = false;
   $temp = $array[$j];
   $array[$j] = $array[$j + 1];
   $array[$j + 1] = $temp;
  }
  }
  if($isSort)
  {
  break;
  }
 }
 var_dump($array);
?>

2.简单选择排序
原理:通过n-i次关键字之间的比较,从n-i+1 个记录中选择关键字最小的记录,并和第i(1<=i<=n)个记录交换         简单选择排序的性能要略优于冒泡排序
时间复杂度:平均情况:O(n2)  最好情况:O(n) 最坏情况:O(n2)
空间复杂度:O(1)
稳定性:不稳定 

//JavaScript
  var array = [23,0,32,45,56,75,43,0,34];

  for(var i = 0; i < array.length - 1; i++)
  {
   var pos = i;
   for(var j = i + 1; j < array.length;j++)
   {
    if(array[j] < array[pos])
    {
     pos=j;
    }
   }
   var temp=array[i];
   array[i]=array[pos];
   array[pos]=temp;
  }
  console.log(array);
<?php
  $array = [23,0,32,45,56,75,43,0,34];
  for($i = 0; $i < count($array); $i++)
 {
  $pos = $i;
  for($j = $i + 1;$j < count($array); $j++)
  {
   if($array[$j] < $array[$pos])
   {
    $pos = $j;
   }
  }
  $temp = $array[$i];
  $array[$i] = $array[$pos];
  $array[$pos] = $temp;
 }
 var_dump($array);

?>

3.直接插入排序
原理:将一个记录插入到已排序好的有序表中,从而得到一个新,记录数增1的有序表。即:先将序列的第1个记录看成是一个有序的子序列,然后从第2个记录逐个进行插入,直至整个序列有序为止。             比冒泡法和选择排序的性能要更好一些
时间复杂度:平均情况:O(n2)  最好情况:O(n) 最坏情况:O(n2)
空间复杂度:O(1)
稳定性:稳定

//JavaScript
  var array = [23,0,32,45,56,75,43,0,34];
  for(var j = 0;j < array.length;j++) {
   var key = array[j];
   var i = j - 1;
   while (i > -1 && array[i] > key)
   {
    array[i + 1] = array[i];
    i = i - 1;
   }
   array[i + 1] = key;
  }
  console.log(array);
<?php
 //直接插入排序
  $array = [23,0,32,45,56,75,43,0,34];
  for($i = 0; $i < count($array); $i++)
 {
  $key = $array[$i];
  $j= $i - 1;
  while($j > -1 && $array[$j] > $key)
  {
   $array[$j +1] = $array[$j];
   $j = $j - 1;
  }
  $array[$j + 1] = $key;
 }
 var_dump($array);
?>

4.快速排序
原理:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
时间复杂度:平均情况:O(nlog2n)  最好情况:O(nlog2n) 最坏情况:O(n2)
空间复杂度:O(nlog2n)

稳定性:不稳定

//JavaScript 快速排序

    var array = [23,0,32,45,56,75,43,0,34];
    var quickSort = function(arr) {
      if (arr.length <= 1) { return arr; }//检查数组的元素个数,如果小于等于1,就返回。
      var pivotIndex = Math.floor(arr.length / 2);//
      var pivot = arr.splice(pivotIndex,1)[0];//选择"基准"(pivot),并将其与原数组分离,
      var left = [];//定义两个空数组,用来存放一左一右的两个子集
      var right = [];
      for (var i = 0; i < arr.length; i++)//遍历数组,小于"基准"的元素放入左边的子集,大于基准的元素放入右边的子集。
      {
        if (arr[i] < pivot) {
          left.push(arr[i]);
        } else {
          right.push(arr[i]);
        }
      }

      return quickSort(left).concat([pivot], quickSort(right));//使用递归不断重复这个过程,就可以得到排序后的数组。
    };
    var newArray=quickSort(array);
    console.log(newArray);
<?php
        $array = [23,0,32,45,56,75,43,0,34];
    function quick_sort($arr) {
      //先判断是否需要继续进行
      $length = count($arr);
      if($length <= 1) {
        return $arr;
      }
    
      $base_num = $arr[0];//选择一个标尺 选择第一个元素

      //初始化两个数组
      $left_array = array();//小于标尺的
      $right_array = array();//大于标尺的
      for($i=1; $i<$length; $i++) {      //遍历 除了标尺外的所有元素,按照大小关系放入两个数组内
        if($base_num > $arr[$i]) {
          //放入左边数组
          $left_array[] = $arr[$i];
        } else {
          //放入右边
          $right_array[] = $arr[$i];
        }
      }
      //再分别对 左边 和 右边的数组进行相同的排序处理方式
      //递归调用这个函数,并记录结果
      $left_array = quick_sort($left_array);
      $right_array = quick_sort($right_array);
      //合并左边 标尺 右边
      return array_merge($left_array, array($base_num), $right_array);
    }
        $newArray=quick_sort($array);
        var_dump($newArray);
?>

5.希尔排序  
原理:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。。
时间复杂度:平均情况:O(n√n)  最好情况:O(nlog2n) 最坏情况:O(n2)
空间复杂度:O(1)

稳定性:不稳定 

//JavaScript 希尔排序
    var array = [23,0,32,45,56,75,43,0,34];
    var shellSort = function (arr)
    {
      var length=arr.length;
      var h=1;
      while(h<length/3)
      {
        h=3*h+1;//设置间隔
      }
      while(h>=1)
      {
        for(var i=h; i<length; i++)
        {
          for(var j=i; j>=h && arr[j]<arr[j-h]; j-=h)
          {
            var temp =arr[j-h];
            arr[j-h]=arr[j];
            arr[j]=temp;
          }
        }
        h=(h-1)/3;
      }
      return arr;
    }
    var newArray = shellSort(array);
    console.log(newArray);
<?php
//希尔排序
    $array = [23,0,32,45,56,75,43,0,34];
    function shellSort($arr)
    {
      $length=count($arr);
      $h=1;
      while($h<$length/3)
      {
        $h=3*$h+1;//设置间隔
      }
      while($h>=1)
      {
        for($i=$h; $i<$length; $i++)
        {
          for($j=$i; $j>=$h && $arr[$j]<$arr[$j-$h]; $j-=$h)
          {
             $temp =$arr[$j-$h];
             $arr[$j-$h]=$arr[$j];
             $arr[$j]=$temp;
          }
        }
        $h=($h-1)/3;
      }
      return $arr;
    }
    $newArray = shellSort($array);
    var_dump($newArray)
?>

6.归并排序
原理:假设初始序列含有n个记录,则可以看成n个有序的子序列,每个子序列的长度为1,然后两两归并,得到(不小于n/2的最小整数)个长度为2或1的有序子序列,再两两归并,...如此重复,直至得到一个长度为n的有序序列为止

 
时间复杂度:平均情况:O(nlog2n)  最好情况:O(nlog2n) 最坏情况:O(nlog2n)
空间复杂度:O(1)

稳定性:稳定 

//JavaScript 归并排序
    function isArray1(arr){
      if(Object.prototype.toString.call(arr) =='[object Array]'){
        return true;
      }else{
        return false;
      }
    }
    function merge(left,right){
      var result=[];
      if(!isArray1(left)){
        left = [left];
      }
      if(!isArray1(right)){
        right = [right];
      }
      while(left.length > 0&& right.length >0){
        if(left[0]<right[0]){
          result.push(left.shift());
        }else{
          result.push(right.shift());
        }
      }
      return result.concat(left).concat(right);
    }

    function mergeSort(arr){
      var len=arr.length;
      var lim ,work=[];
      var i,j,k;
      if(len ==1){
        return arr;
      }
      for(i=0;i<len;i++){
        work.push(arr[i]);
      }
      work.push([]);
      for(lim=len;lim>1;){//lim为分组长度
        for(j=0,k=0;k<lim;j++,k=k+2){
          work[j]=merge(work[k],work[k+1]);
        }
        work[j]=[];
        lim=Math.floor((lim+1)/2);
      }
      return work[0];
    }
    var array = [23,0,32,45,56,75,43,0,34];
    
    console.log(mergeSort(array));
<?php 
   //归并排序
    function mergeSort(&$arr) {
      $len = count($arr);//求得数组长度
     
      mSort($arr, 0, $len-1);
    }
    //实际实现归并排序的程序
    function mSort(&$arr, $left, $right) {
     
      if($left < $right) {
        //说明子序列内存在多余1个的元素,那么需要拆分,分别排序,合并
        //计算拆分的位置,长度/2 去整
        $center = floor(($left+$right) / 2);
        //递归调用对左边进行再次排序:
        mSort($arr, $left, $center);
        //递归调用对右边进行再次排序
        mSort($arr, $center+1, $right);
        //合并排序结果
        mergeArray($arr, $left, $center, $right);
      }
    }

    //将两个有序数组合并成一个有序数组
    function mergeArray(&$arr, $left, $center, $right) {
      //设置两个起始位置标记
      $a_i = $left;
      $b_i = $center+1;
      while($a_i<=$center && $b_i<=$right) {
        //当数组A和数组B都没有越界时
        if($arr[$a_i] < $arr[$b_i]) {
          $temp[] = $arr[$a_i++];
        } else {
          $temp[] = $arr[$b_i++];
        }
      }
      //判断 数组A内的元素是否都用完了,没有的话将其全部插入到C数组内:
      while($a_i <= $center) {
        $temp[] = $arr[$a_i++];
      }
      //判断 数组B内的元素是否都用完了,没有的话将其全部插入到C数组内:
      while($b_i <= $right) {
        $temp[] = $arr[$b_i++];
      }
     
      //将$arrC内排序好的部分,写入到$arr内:
      for($i=0, $len=count($temp); $i<$len; $i++) {
        $arr[$left+$i] = $temp[$i];
      }
     
    }

    $arr = array(23,0,32,45,56,75,43,0,34);
    mergeSort($arr);
    var_dump($arr);
?>

7.堆排序
原理:堆排序就是利用堆进行排序的方法.基本思想是:将待排序的序列构造成一个大顶堆.此时,整个序列的最大值就是堆顶 的根结点.将它移走(其实就是将其与堆数组的末尾元素交换, 此时末尾元素就是最大值),然后将剩余的n-1个序列重新构造成一个堆,这样就会得到n个元素的次大值.如此反复执行,便能得到一个有序序列了
时间复杂度:平均情况:O(nlog2n)  最好情况:O(nlog2n) 最坏情况:O(nlog2n)
空间复杂度:O(1)
稳定性:不稳定 

//JavaScript 堆排序  
    var array = [23,0,32,45,56,75,43,0,34];
    function heapSort(array)
    {
      for (var i = Math.floor(array.length / 2); i >= 0; i--)
      {
        heapAdjust(array, i, array.length - 1); //将数组array构建成一个大顶堆
      }
      for (i = array.length - 1; i >= 0; i--)
      {
        /*把根节点交换出去*/
        var temp = array[i];
        array[i] = array[0];
        array[0] = temp;
        /*余下的数组继续构建成大顶堆*/
        heapAdjust(array, 0, i - 1);
      }
      return array;
    }

    function heapAdjust(array, start, max)
    {
      var temp = array[start];//temp是根节点的值
      for (var j = 2 * start; j < max; j *= 2)
      {
        if (j < max && array[j] < array[j + 1])
        { //取得较大孩子的下标
          ++j;
        }
        if (temp >= array[j])
          break;
        array[start] = array[j];
        start = j;
      }
      array[start] = temp;
    }
    var newArray = heapSort(array);
    console.log(newArray);
<?php
  //堆排序
  function heapSort(&$arr) {
    #初始化大顶堆
    initHeap($arr, 0, count($arr) - 1);
    
    #开始交换首尾节点,并每次减少一个末尾节点再调整堆,直到剩下一个元素
    for($end = count($arr) - 1; $end > 0; $end--) {
      $temp = $arr[0];
      $arr[0] = $arr[$end];
      $arr[$end] = $temp;
      ajustNodes($arr, 0, $end - 1);
    }
  }
  
  #初始化最大堆,从最后一个非叶子节点开始,最后一个非叶子节点编号为 数组长度/2 向下取整
  function initHeap(&$arr) {
    $len = count($arr);
    for($start = floor($len / 2) - 1; $start >= 0; $start--) {
      ajustNodes($arr, $start, $len - 1);
    }
  }
  
  #调整节点
  #@param $arr  待调整数组
  #@param $start  调整的父节点坐标
  #@param $end  待调整数组结束节点坐标
  function ajustNodes(&$arr, $start, $end) {
    $maxInx = $start;
    $len = $end + 1;  #待调整部分长度
    $leftChildInx = ($start + 1) * 2 - 1;  #左孩子坐标
    $rightChildInx = ($start + 1) * 2;  #右孩子坐标
    
    #如果待调整部分有左孩子
    if($leftChildInx + 1 <= $len) {
      #获取最小节点坐标
      if($arr[$maxInx] < $arr[$leftChildInx]) {
        $maxInx = $leftChildInx;
      }
      
      #如果待调整部分有右子节点
      if($rightChildInx + 1 <= $len) {
        if($arr[$maxInx] < $arr[$rightChildInx]) {
          $maxInx = $rightChildInx;
        }
      }
    }
    
    #交换父节点和最大节点
    if($start != $maxInx) {
      $temp = $arr[$start];
      $arr[$start] = $arr[$maxInx];
      $arr[$maxInx] = $temp;
      
      #如果交换后的子节点还有子节点,继续调整
      if(($maxInx + 1) * 2 <= $len) {
        ajustNodes($arr, $maxInx, $end);
      }
    }
  }
  
  $arr = array(23,0,32,45,56,75,43,0,34);
  heapSort($arr);
  var_dump($arr);
?>

8.基数排序
原理:将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数。

时间复杂度:平均情况:O(d(r+n))  最好情况:O(d(n+rd)) 最坏情况:O(d(r+n))   r:关键字的基数   d:长度  n:关键字个数
空间复杂度:O(rd+n)
稳定性:稳定 

<?php
   #基数排序,此处仅对正整数进行排序,至于负数和浮点数,需要用到补码,各位有兴趣自行研究
   
   #计数排序
   #@param $arr 待排序数组
   #@param $digit_num 根据第几位数进行排序
   function counting_sort(&$arr, $digit_num = false) {
     if ($digit_num !== false) { #如果参数$digit_num不为空,则根据元素的第$digit_num位数进行排序
       for ($i = 0; $i < count($arr); $i++) {
         $arr_temp[$i] = get_specific_digit($arr[$i], $digit_num);
       } 
     } else {
       $arr_temp = $arr;
     }
 
     $max = max($arr);
     $time_arr = array(); #储存元素出现次数的数组
 
     #初始化出现次数数组
     for ($i = 0; $i <= $max; $i++) {
       $time_arr[$i] = 0;
     }
 
     #统计每个元素出现次数
     for ($i = 0; $i < count($arr_temp); $i++) {
       $time_arr[$arr_temp[$i]]++;
     }
 
     #统计每个元素比其小或相等的元素出现次数
     for ($i = 0; $i < count($time_arr) - 1; $i++) {
       $time_arr[$i + 1] += $time_arr[$i];
     }
 
     #利用出现次数对数组进行排序
     for($i = count($arr) - 1; $i >= 0; $i--) {
       $sorted_arr[$time_arr[$arr_temp[$i]] - 1] = $arr[$i];
       $time_arr[$arr_temp[$i]]--;
     }
 
     $arr = $sorted_arr;
     ksort($arr);  #忽略这次对key排序的效率损耗
   }
 
   #计算某个数的位数
   function get_digit($number) {
     $i = 1;
     while ($number >= pow(10, $i)) {
      $i++;
     }

     return $i;
   }
 
   #获取某个数字的从个位算起的第i位数
   function get_specific_digit($num, $i) {
     if ($num < pow(10, $i - 1)) {
       return 0;
     }
     return floor($num % pow(10, $i) / pow(10, $i - 1));
   }
 
   #基数排序,以计数排序作为子排序过程
   function radix_sort(&$arr) {
     #先求出数组中最大的位数
     $max = max($arr);
     $max_digit = get_digit($max);
 
     for ($i = 1; $i <= $max_digit; $i++) {
       counting_sort($arr, $i);
     }  
   }
 
 
   $arr = array(23,0,32,45,56,75,43,0,34);
   radix_sort($arr);
 
   var_dump($arr);
?>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript 数据类型转换(parseInt,parseFloat)
Jul 20 Javascript
写自已的js类库需要的核心代码
Jul 16 Javascript
js判断样式className同时增加class或删除class
Jan 30 Javascript
javascript中call和apply的用法示例分析
Apr 02 Javascript
jQuery siblings()用法实例详解
Apr 26 Javascript
bootstrap模态框跳转到当前模板页面 框消失了而背景存在问题的解决方法
Nov 30 Javascript
JS数组返回去重后数据的方法解析
Jan 03 Javascript
EasyUI的DataGrid每行数据添加操作按钮的实现代码
Aug 22 Javascript
webstorm中vue语法的支持详解
May 09 Javascript
vue升级之路之vue-router的使用教程
Aug 14 Javascript
JS实现方形抽奖效果
Aug 27 Javascript
vue实现分页加载效果
Dec 24 Javascript
微信支付 JS API支付接口详解
Jul 11 #Javascript
判断输入的字符串是否是日期格式的简单方法
Jul 11 #Javascript
JS判断日期格式是否合法的简单实例
Jul 11 #Javascript
深入浅析JavaScript中的scrollTop
Jul 11 #Javascript
js鼠标单击和双击事件冲突问题的快速解决方法
Jul 11 #Javascript
js 弹出对话框(遮罩)透明,可拖动的简单实例
Jul 11 #Javascript
Bootstrap3制作搜索框样式的方法
Jul 11 #Javascript
You might like
一些花式咖啡的配方
2021/03/03 冲泡冲煮
php仿QQ验证码的实例分析
2013/07/01 PHP
学习php设计模式 php实现策略模式(strategy)
2015/12/07 PHP
PHP数组的定义、初始化和数组元素的显示实现代码
2016/11/05 PHP
利用PHP抓取百度阅读的方法示例
2016/12/18 PHP
jQuery 注意事项 与原因分析
2009/04/24 Javascript
js螺旋动画效果的具体实例
2013/11/15 Javascript
浅析jquery某一元素重复绑定的问题
2014/01/03 Javascript
jquery实现的随机多彩tag标签随机颜色和字号大小效果
2014/03/27 Javascript
jQuery遍历json中多个map的方法
2015/02/12 Javascript
javascript实现随时变化着的背景颜色
2015/04/02 Javascript
JavaScript实现同一页面内两个表单互相传值的方法
2015/08/12 Javascript
jquery带下拉菜单和焦点图代码分享
2015/08/24 Javascript
JavaScript编写点击查看大图的页面半透明遮罩层效果实例
2016/05/09 Javascript
AngularJS $injector 依赖注入详解
2016/09/14 Javascript
JS对象与json字符串相互转换实现方法示例
2018/06/14 Javascript
详解Vue demo实现商品列表的展示
2019/05/07 Javascript
浅谈Vue的响应式原理
2019/05/30 Javascript
python实现给字典添加条目的方法
2014/09/25 Python
Python搭建APNS苹果推送通知推送服务的相关模块使用指南
2016/06/02 Python
使用Python操作excel文件的实例代码
2017/10/15 Python
Python实现快速傅里叶变换的方法(FFT)
2018/07/21 Python
python 随机打乱 图片和对应的标签方法
2018/12/14 Python
Pyinstaller打包.py生成.exe的方法和报错总结
2019/04/02 Python
python实现五子棋小程序
2019/06/18 Python
python爬虫增加访问量的方法
2019/08/22 Python
Python日志syslog使用原理详解
2020/02/18 Python
无惧面试,带你搞懂python 装饰器
2020/08/17 Python
python+requests实现接口测试的完整步骤
2020/10/27 Python
检测用户浏览器是否支持CSS3的方法
2009/08/29 HTML / CSS
电气工程及其自动化学生实习自我鉴定
2013/09/19 职场文书
Java实现简易的分词器功能
2021/06/15 Java/Android
Redis性能监控的实现
2021/07/09 Redis
JavaScript中isPrototypeOf函数
2021/11/07 Javascript
Python中第三方库Faker的使用详解
2022/04/02 Python
教你在 Java 中实现 Dijkstra 最短路算法的方法
2022/04/08 Java/Android