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 相关文章推荐
js判断生效时间不得大于失效时间的思路及代码
Apr 23 Javascript
javascript在网页中实现读取剪贴板粘贴截图功能
Jun 07 Javascript
基于javascript实现图片左右切换效果
Jan 25 Javascript
JavaScript几种数组去掉重复值的方法推荐
Apr 12 Javascript
javascript js 操作数组 增删改查的简单实现
Jun 20 Javascript
Javascript字符串常用方法详解
Jul 21 Javascript
微信小程序 在Chrome浏览器上运行以及WebStorm的使用
Sep 27 Javascript
JS字符串按逗号和回车分隔的方法
Apr 25 Javascript
JQuery和html+css实现带小圆点和左右按钮的轮播图实例
Jul 22 jQuery
Angular PWA使用的Demo示例
Jan 31 Javascript
javascript使用链接跨域下载图片
Nov 01 Javascript
js实现盒子拖拽动画效果
Aug 09 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
PHP 类型转换函数intval
2009/06/20 PHP
PHP应用JSON技巧讲解
2013/02/03 PHP
基于AppServ,XAMPP,WAMP配置php.ini去掉警告信息(NOTICE)的方法详解
2013/05/07 PHP
windows下安装php的memcache模块的方法
2015/04/07 PHP
PHP基于工厂模式实现的计算器实例
2015/07/16 PHP
Laravel 5.4重新登录实现跳转到登录前页面的原理和方法
2017/07/13 PHP
PHP微信开发之微信录音临时转永久存储
2018/01/26 PHP
出现“不能执行已释放的Script代码”错误的原因及解决办法
2007/08/29 Javascript
JQUERY复选框CHECKBOX全选,取消全选
2008/08/30 Javascript
js 省地市级联选择
2010/02/07 Javascript
Javascript 获取链接(url)参数的方法[正则与截取字符串]
2010/02/09 Javascript
用js正确判断用户名cookie是否存在的方法
2014/01/28 Javascript
js 金额格式化来回转换示例
2014/02/23 Javascript
JS实现向表格中动态添加行的方法
2015/03/30 Javascript
JavaScript中数据结构与算法(二):队列
2015/06/19 Javascript
jQuery实现图片上传和裁剪插件Croppie
2015/11/29 Javascript
由浅入深讲解Javascript继承机制与simple-inheritance源码分析
2015/12/13 Javascript
bootstrap弹出层的多种触发方式
2017/05/10 Javascript
微信小程序基于picker实现级联菜单
2019/02/15 Javascript
express框架下使用session的方法
2019/07/31 Javascript
使用Vue实现简单计算器
2020/02/25 Javascript
webpack3.0升级4.0的方法步骤
2020/04/02 Javascript
[01:00:14]2018DOTA2亚洲邀请赛 4.6 淘汰赛 VP vs TNC 第三场
2018/04/10 DOTA
分享Python文本生成二维码实例
2016/01/06 Python
利用python程序生成word和PDF文档的方法
2017/02/14 Python
python字典快速保存于读取的方法
2018/03/23 Python
python将.ppm格式图片转换成.jpg格式文件的方法
2018/10/27 Python
解决img标签上下出现间隙的方法
2016/12/14 HTML / CSS
兰芝美国网上商城:购买LANEIGE睡眠面膜等
2017/06/30 全球购物
Lulu Guinness露露·吉尼斯官网:红唇包
2019/02/03 全球购物
日本AOKI官方商城:AOKI西装
2020/06/11 全球购物
班风口号
2014/06/18 职场文书
2014财产信托协议书范本
2014/11/18 职场文书
小兵张嘎观后感300字
2015/06/03 职场文书
MySQL库表名大小写的选择
2021/06/05 MySQL
Vite + React从零开始搭建一个开源组件库
2022/06/25 Javascript