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 相关文章推荐
提高网站信任度的技巧
Oct 17 Javascript
JavaScript几种形式的树结构菜单
May 10 Javascript
Node.js事件循环(Event Loop)和线程池详解
Jan 28 Javascript
js实现网页图片延时加载 提升网页打开速度
Jan 26 Javascript
用原生js统计文本行数的简单示例
Aug 19 Javascript
纯前端JavaScript实现Excel IO案例分享
Aug 26 Javascript
无法获取隐藏元素宽度和高度的解决方案
Mar 07 Javascript
Vue单文件组件的如何使用方式介绍
Jul 28 Javascript
详解Vue取消eslint语法限制
Aug 04 Javascript
使用kbone解决Vue项目同时支持小程序问题
Nov 08 Javascript
vue循环中点击选中再点击取消(单选)的实现
Sep 10 Javascript
解决idea开发遇到javascript动态添加html元素时中文乱码的问题
Sep 29 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
基于python发送邮件的乱码问题的解决办法
2013/04/25 PHP
php中in_array函数用法探究
2014/11/25 PHP
thinkphp3.2.2实现生成多张缩略图的方法
2014/12/19 PHP
微信access_token的获取开发示例
2015/04/16 PHP
PHP Socket网络操作类定义与用法示例
2017/08/30 PHP
使javascript也能包含文件
2006/10/26 Javascript
对YUI扩展的Gird组件 Part-1
2007/03/10 Javascript
Knockoutjs快速入门(经典)
2012/12/24 Javascript
jquery 提示信息显示后自动消失的具体实现
2013/12/18 Javascript
JQuery对表格进行操作的常用技巧总结
2014/04/23 Javascript
对比分析json及XML
2014/11/28 Javascript
nodeJS代码实现计算交社保是否合适
2015/03/09 NodeJs
Javascript实现飞动广告效果的方法
2015/05/25 Javascript
jquery.validate提示错误信息位置方法
2016/01/22 Javascript
AngularJS中的指令全面解析(必看)
2016/05/20 Javascript
BootStrap智能表单实战系列(七)验证的支持
2016/06/13 Javascript
纯原生js实现table表格的增删
2017/01/05 Javascript
AngularJS 验证码60秒倒计时功能的实现
2017/06/05 Javascript
Vue 自定义动态组件实例详解
2018/03/28 Javascript
学习React中ref的两个demo示例
2018/08/14 Javascript
用Fundebug插件记录网络请求异常的方法
2019/02/21 Javascript
vue+element table表格实现动态列筛选的示例代码
2021/01/14 Vue.js
python中Matplotlib实现绘制3D图的示例代码
2017/09/04 Python
Python matplotlib绘图可视化知识点整理(小结)
2018/03/16 Python
PyQt5 QSerialPort子线程操作的实现
2018/04/21 Python
python配置文件写入过程详解
2019/10/19 Python
使用 PyTorch 实现 MLP 并在 MNIST 数据集上验证方式
2020/01/08 Python
python微信公众号开发简单流程实现
2020/03/09 Python
Python requests模块session代码实例
2020/04/14 Python
中国综合网上购物商城:苏宁易购
2016/08/09 全球购物
eDreams巴西:廉价机票,酒店优惠和度假套餐
2017/04/14 全球购物
来自世界各地的饮料:Flavourly
2019/05/06 全球购物
美国椅子和沙发制造商:La-Z-Boy
2020/10/25 全球购物
护理专业应届毕业生推荐信
2013/11/15 职场文书
骨干教师培训方案
2014/05/06 职场文书
idea下配置tomcat避坑详解
2022/04/12 Servers