八大排序算法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);
?>
八大排序算法JS及PHP代码实现的更多相关文章
- 八大排序算法详解(动图演示 思路分析 实例代码java 复杂度分析 适用场景)
一.分类 1.内部排序和外部排序 内部排序:待排序记录存放在计算机随机存储器中(说简单点,就是内存)进行的排序过程. 外部排序:待排序记录的数量很大,以致于内存不能一次容纳全部记录,所以在排序过程中需 ...
- 八大排序算法C++代码实现
八大排序算法 概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 我们这里说说八大排序就是内部排序 ...
- 八大排序算法总结与java实现(转)
八大排序算法总结与Java实现 原文链接: 八大排序算法总结与java实现 - iTimeTraveler 概述 直接插入排序 希尔排序 简单选择排序 堆排序 冒泡排序 快速排序 归并排序 基数排序 ...
- 八大排序算法的 Python 实现
转载: 八大排序算法的 Python 实现 本文用Python实现了插入排序.希尔排序.冒泡排序.快速排序.直接选择排序.堆排序.归并排序.基数排序. 1.插入排序 描述 插入排序的基本操作就是将一个 ...
- 八大排序算法Java实现
本文对常见的排序算法进行了总结. 常见排序算法如下: 直接插入排序 希尔排序 简单选择排序 堆排序 冒泡排序 快速排序 归并排序 基数排序 它们都属于内部排序,也就是只考虑数据量较小仅需要使用内存的排 ...
- Python实现八大排序算法(转载)+ 桶排序(原创)
插入排序 核心思想 代码实现 希尔排序 核心思想 代码实现 冒泡排序 核心思想 代码实现 快速排序 核心思想 代码实现 直接选择排序 核心思想 代码实现 堆排序 核心思想 代码实现 归并排序 核心思想 ...
- 【Python】八大排序算法的比较
排序是数据处理比较核心的操作,八大排序算法分别是:直接插入排序.希尔排序.简单选择排序.堆排序.冒泡排序.快速排序.归并排序.基数排序 以下是排序图解: 直接插入排序 思想 直接插入排序是一种最简单的 ...
- 八大排序算法 JAVA实现 亲自测试 可用!
今天很高兴 终于系统的实现了八大排序算法!不说了 直接上代码 !代码都是自己敲的, 亲测可用没有问题! 另:说一下什么是八大排序算法: 插入排序 希尔排序 选择排序 堆排序 冒泡排序 快速排序 归并排 ...
- Python - 八大排序算法
1.序言 本文使用Python实现了一些常用的排序方法.文章结构如下: 1.直接插入排序 2.希尔排序 3.冒泡排序 4.快速排序 5.简单选择排序 6.堆排序 7.归并排序 8.基数排序 上述所有的 ...
随机推荐
- 使用Java解析XML文件或XML字符串的例子
转: 使用Java解析XML文件或XML字符串的例子 2017年09月16日 11:36:18 inter_peng 阅读数:4561 标签: JavaXML-Parserdom4j 更多 个人分类: ...
- bzoj 1003 最短路+dp
1003: [ZJOI2006]物流运输 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 8249 Solved: 3464[Submit][Stat ...
- zabbix 邮件配置
一.系统和版本 操作系统:centos7 zabbix版本: 3.2.5 二.安装sendmail yum -y install sendmail systemctl enable sendmail ...
- 一元回归_ols参数解读(推荐AAA)
sklearn实战-乳腺癌细胞数据挖掘(博客主亲自录制视频教程) https://study.163.com/course/introduction.htm?courseId=1005269003&a ...
- 二型错误和功效(Type II Errors and Test Power)
sklearn实战-乳腺癌细胞数据挖掘(博主亲自录制视频教程) https://study.163.com/course/introduction.htm?courseId=1005269003&am ...
- P值解释和误区
sklearn实战-乳腺癌细胞数据挖掘(博主亲自录制视频教程) https://study.163.com/course/introduction.htm?courseId=1005269003&am ...
- ClassNotFoundException:com.sun.xml.bind.v2.ContextFactory
项目中引入hive-jdbc-1.2.1-standalone.jar包之后,报错如下: Caused by: javax.xml.bind.JAXBException: Provider com.s ...
- [php排错] Forbidden You don't have permission to access / on this server.
刚开始接触PHP,在搭建完环境后发现输入127.0.0.1可以访问界面,但是输入http://localhost却提醒无权访问,在百度之后发现是php中的httpd.conf的作用 在wamp中搜索发 ...
- javascript操作对象的方法
with 确定某个对象的作用区域,在with代码段内的次对象的属性或方法可以直接使用. 例: //比如stu中有name,age属性和walk方法 with(stu) { alert(name+&qu ...
- 认识单点登录cas
么是单点登录?单点登录全称Single Sign On(以下简称SSO),是指在多系统应用群中登录一个系统,便可在其他所有系统中得到授权而无需再次登录,包括单点登录与单点注销两部分 1.登录 相比于单 ...