php和JavaScript实现八大排序算法
来源:互联网 发布:中信国安历史交易数据 编辑:程序博客网 时间:2024/05/21 01:27
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
);
?>
- php和JavaScript实现八大排序算法
- 八大排序算法的实现和分析
- 八大排序算法实现
- 八大排序算法实现
- 八大排序算法的实现
- 八大排序算法的实现
- 八大排序算法-java实现
- 八大排序算法 java实现
- java八大排序算法实现
- Python实现八大排序算法
- 八大排序算法及实现
- 八大排序算法自我实现
- 八大排序算法java实现
- 八大排序算法-java实现
- Java实现八大排序算法
- 八大排序算法JAVA实现
- 八大排序算法C实现
- 八大排序算法PYTHON实现
- next() 与 nextLine()的区别
- 剑指offer--包含min函数的栈
- Ubuntu 16.04下安装ssh远程无法连接的解决方法
- 文章标题
- 欢迎使用CSDN-markdown编辑器
- php和JavaScript实现八大排序算法
- PAT --- 1010. 一元多项式求导 (25)
- Java测试框架Mockito源码分析
- C#泛型约束与调用
- leetcode之二叉树类之二叉树中序遍历运用-----OJ173/230/98/99/285 二叉树迭代器/BST第K小元素/判断BST是否合法/恢复BST/二叉树下个节点
- Failed to decode downloaded font
- 跳跃游戏(一,二)
- 用empty()来代替检查size()是否为空
- SSH框架中文乱码终极解决方案