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

 更新时间:2016年07月12日 08:49:36   作者:simpleton  
这篇文章主要为大家详细介绍了JS及PHP代码编写八大排序算法的相关资料,感兴趣的小伙伴们可以参考一下

从学习数据结构开始就接触各种算法基础,但是自从应付完考试之后就再也没有练习过,当在开发的时候也是什么时候使用什么时候去查一下,现在在学习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);
?>

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

相关文章

  • 微信小程序pinker组件使用实现自动相减日期

    微信小程序pinker组件使用实现自动相减日期

    这篇文章主要介绍了微信小程序pinker组件使用实现自动相减日期,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-05-05
  • 由浅入深讲解Javascript继承机制与simple-inheritance源码分析

    由浅入深讲解Javascript继承机制与simple-inheritance源码分析

    Javascript语言对继承实现的并不好,需要工程师自己去实现一套完整的继承机制。下面我们由浅入深的系统掌握使用javascript继承的技巧,对javascript继承相关知识感兴趣的朋友一起看看吧
    2015-12-12
  • JS组件系列之Bootstrap table表格组件神器【终结篇】

    JS组件系列之Bootstrap table表格组件神器【终结篇】

    Bootstrap Table是轻量级的和功能丰富的以表格的形式显示的数据,支持单选,复选框,排序,分页,显示/隐藏列,固定标题滚动表,响应式设计,Ajax加载JSON数据,点击排序的列,卡片视图等。本文给大家介绍JS组件系列之Bootstrap table表格组件神器【终结篇】,一起学习吧
    2016-05-05
  • ionic中的$ionicPlatform.ready事件中的通用设置

    ionic中的$ionicPlatform.ready事件中的通用设置

    $ionicPlatform.ready事件是用于检测当前的平台是否就绪的事件,相当于基于document的deviceready事件, 在app中一些通用关于设备的设置必须在这个事件中处理
    2017-06-06
  • webpack项目使用eslint建立代码规范实现

    webpack项目使用eslint建立代码规范实现

    这篇文章主要介绍了webpack项目使用eslint建立代码规范实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-05-05
  • 微信小程序在{{ }}中直接使用函数的方法示例

    微信小程序在{{ }}中直接使用函数的方法示例

    最近在学习微信小程序,在学习中遇到了一些问题,所以进行了总结了下,这篇文章主要给大家介绍了关于微信小程序在{{ }}中直接使用函数的相关资料,需要的朋友可以参考下
    2021-06-06
  • JS前端接口防止重复请求的三种实现方案

    JS前端接口防止重复请求的三种实现方案

    前段时间心血来潮,想把项目的前端都做一下接口防止重复请求的处理,虽然大部分的接口处理我们都是加了loading的,但又不能确保真的是每个接口都加了的,下面就来总结一下这次的防重复请求的实现方案,需要的朋友可以参考下
    2024-03-03
  • JS 组件系列之Bootstrap Table的冻结列功能彻底解决高度问题

    JS 组件系列之Bootstrap Table的冻结列功能彻底解决高度问题

    这篇文章主要介绍了JS 组件系列之Bootstrap Table的冻结列功能彻底解决高度问题,需要的朋友可以参考下
    2017-06-06
  • 微信小程序实现锚点功能

    微信小程序实现锚点功能

    这篇文章主要为大家详细介绍了微信小程序实现锚点功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-11-11
  • JavaScript实现模仿桌面窗口的方法

    JavaScript实现模仿桌面窗口的方法

    这篇文章主要介绍了JavaScript实现模仿桌面窗口的方法,可实现模仿桌面窗口的打开、关闭、移动、缩放及最大化、最小化等功能,需要的朋友可以参考下
    2015-07-07

最新评论