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文件的小脚本
Jun 28 Javascript
DWR Ext 加载数据
Mar 22 Javascript
js注意img图片的onerror事件的分析
Jan 01 Javascript
让js弹出窗口居前显示的实现方法
Jul 10 Javascript
判断输入是否为空,获得输入类型的JS代码
Oct 30 Javascript
jQuery通过点击行来删除HTML表格行的实现示例
Sep 10 Javascript
基于jQuery Circlr插件实现产品图片360度旋转
Sep 20 Javascript
WebApi+Bootstrap+KnockoutJs打造单页面程序
May 16 Javascript
Jquery循环截取字符串的方法(多出的字符串处理成&quot;...&quot;)
Nov 28 Javascript
vue 中引用gojs绘制E-R图的方法示例
Aug 24 Javascript
JS实现可针对算术表达式求值的计算器功能示例
Sep 04 Javascript
ES6箭头函数和扩展实例分析
May 23 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+mysql来做一个功能强大的在线计算器
2010/10/12 PHP
理解php原理的opcodes(操作码)
2010/10/26 PHP
PHP程序漏洞产生的原因分析与防范方法说明
2014/03/06 PHP
详谈PHP面向对象中常用的关键字和魔术方法
2017/02/04 PHP
Yii框架日志记录Logging操作示例
2018/07/12 PHP
学习ExtJS TextField常用方法
2009/10/07 Javascript
jquery学习笔记二 实现可编辑的表格
2010/04/09 Javascript
javascript中获取下个月一号,是星期几
2012/06/01 Javascript
JS获取当前日期和时间的简单实例
2013/11/19 Javascript
jQuery实现进度条效果代码
2015/12/17 Javascript
微信小程序 条件渲染详解
2016/10/09 Javascript
jQuery Validate验证框架详解(推荐)
2016/12/17 Javascript
使用JS在浏览器中判断当前网络连接状态的几种方法
2017/05/05 Javascript
Angular2 组件通信的实例代码
2017/06/23 Javascript
vue router-link传参以及参数的使用实例
2017/11/10 Javascript
js实现rem自动匹配计算font-size的示例
2017/11/18 Javascript
Vue2.0 实现单选互斥的方法
2018/04/13 Javascript
vue进入页面时滚动条始终在底部代码实例
2019/03/26 Javascript
JavaScript 面向对象基础简单示例
2019/10/02 Javascript
解决vue prop传值default属性如何使用,为何不生效的问题
2020/09/21 Javascript
教你如何将 Sublime 3 打造成 Python/Django IDE开发利器
2014/07/04 Python
python实现支持目录FTP上传下载文件的方法
2015/06/03 Python
Python脚本实现自动发带图的微博
2016/04/27 Python
python获取微信企业号打卡数据并生成windows计划任务
2019/04/30 Python
react+django清除浏览器缓存的几种方法小结
2019/07/17 Python
python爬虫爬取幽默笑话网站
2019/10/24 Python
python在linux环境下安装skimage的示例代码
2020/10/14 Python
canvas绘制图片drawImage使用方法
2020/09/15 HTML / CSS
伦敦一卡通:The London Pass
2018/11/30 全球购物
公共场所卫生管理制度
2015/08/05 职场文书
教学副校长工作总结
2015/08/13 职场文书
环保主题班会教案
2015/08/13 职场文书
2016年春季运动会广播稿
2015/08/19 职场文书
Python+Appium自动化测试的实战
2021/06/30 Python
纯CSS3实现div按照顺序出入效果
2021/07/15 HTML / CSS
Win11 22H2 2022怎么更新? 获得Win1122H22022版本升级技巧
2022/09/23 数码科技