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

八大排序算法JS及PHP代码实现的更多相关文章

  1. 八大排序算法详解(动图演示 思路分析 实例代码java 复杂度分析 适用场景)

    一.分类 1.内部排序和外部排序 内部排序:待排序记录存放在计算机随机存储器中(说简单点,就是内存)进行的排序过程. 外部排序:待排序记录的数量很大,以致于内存不能一次容纳全部记录,所以在排序过程中需 ...

  2. 八大排序算法C++代码实现

    八大排序算法 概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 我们这里说说八大排序就是内部排序 ...

  3. 八大排序算法总结与java实现(转)

    八大排序算法总结与Java实现 原文链接: 八大排序算法总结与java实现 - iTimeTraveler 概述 直接插入排序 希尔排序 简单选择排序 堆排序 冒泡排序 快速排序 归并排序 基数排序 ...

  4. 八大排序算法的 Python 实现

    转载: 八大排序算法的 Python 实现 本文用Python实现了插入排序.希尔排序.冒泡排序.快速排序.直接选择排序.堆排序.归并排序.基数排序. 1.插入排序 描述 插入排序的基本操作就是将一个 ...

  5. 八大排序算法Java实现

    本文对常见的排序算法进行了总结. 常见排序算法如下: 直接插入排序 希尔排序 简单选择排序 堆排序 冒泡排序 快速排序 归并排序 基数排序 它们都属于内部排序,也就是只考虑数据量较小仅需要使用内存的排 ...

  6. Python实现八大排序算法(转载)+ 桶排序(原创)

    插入排序 核心思想 代码实现 希尔排序 核心思想 代码实现 冒泡排序 核心思想 代码实现 快速排序 核心思想 代码实现 直接选择排序 核心思想 代码实现 堆排序 核心思想 代码实现 归并排序 核心思想 ...

  7. 【Python】八大排序算法的比较

    排序是数据处理比较核心的操作,八大排序算法分别是:直接插入排序.希尔排序.简单选择排序.堆排序.冒泡排序.快速排序.归并排序.基数排序 以下是排序图解: 直接插入排序 思想 直接插入排序是一种最简单的 ...

  8. 八大排序算法 JAVA实现 亲自测试 可用!

    今天很高兴 终于系统的实现了八大排序算法!不说了 直接上代码 !代码都是自己敲的, 亲测可用没有问题! 另:说一下什么是八大排序算法: 插入排序 希尔排序 选择排序 堆排序 冒泡排序 快速排序 归并排 ...

  9. Python - 八大排序算法

    1.序言 本文使用Python实现了一些常用的排序方法.文章结构如下: 1.直接插入排序 2.希尔排序 3.冒泡排序 4.快速排序 5.简单选择排序 6.堆排序 7.归并排序 8.基数排序 上述所有的 ...

随机推荐

  1. tableau学习

    一.维度 度量 1. 连接到新数据源时,Tableau 会将该数据源中的每个字段分配给“数据”窗格的“维度”区域或“度量”区域,具体情况视字段包含的数据类型而定. 例如: 2. tableau中的字段 ...

  2. angular2 获取到的数据无法实时更新的问题

    在修改完组件数据之后调用下面两句: this.changeDetectorRef.markForCheck(); this.changeDetectorRef.detectChanges(); 注入到 ...

  3. php输出控制函数存在的意义

    因为http协议的限制(前几行必须是协议信息,然后一个空行,然后才是用户需要的内容), 需要保证header信息在其他内容之前发送,否则浏览器无法解析服务器返回的内容.

  4. @Springboot搭建项目controller层接收json格式的对象失败

    今天在使用swagger2测试的时候出错 1.@requestBody注解常用来处理content-type不是默认的application/x-www-form-urlcoded编码的内容,比如说: ...

  5. 微信小程序语音识别

    语音识别现在已经发展的很成熟了,经过比对发现百度对开发者比较友好,提供很多种语言的SDK,对python来说直接安装 pip install baidu-aip 文档写的也不错  具体参考:http: ...

  6. Drools规则引擎环境搭建

    Drools 是一款基于Java 的开源规则引擎,所以在使用Drools 之前需要在开发机器上安装好JDK 环境,Drools5 要求的JDK 版本要在1.5 或以上. Drools5 提供了一个基于 ...

  7. POJ 3348 Cows 凸包 求面积

    LINK 题意:给出点集,求凸包的面积 思路:主要是求面积的考察,固定一个点顺序枚举两个点叉积求三角形面积和除2即可 /** @Date : 2017-07-19 16:07:11 * @FileNa ...

  8. unZip/Zip的安装

    1.apt-get安装: apt-get install zip 2.yum安装: yum install -y unzip zip

  9. bluebird -1 New Promise方法

    new Promise new Promise(function(function resolve, function reject) resolver) -> Promise 创建一个Prom ...

  10. .NET面试题系列(二)GC

    序言 对象生存期 Phone item=new Phone() 在C#中,创建对象使用的是new关键字. 要注意的是new操作返回的并不是对象本身,而是对象的一个引用(Reference). 如果使用 ...