js快速排序算法
⑴ JS实现随机化快速排序的实例代码
算法的平均时间复杂度为O(nlogn)。但是当输入是已经排序的数组或几乎排好序的输入,时间复杂度却为O(n^2)。为解决这一问题并保证平均时间复杂度为O(nlogn)的方法是引入预处理步骤,它惟一的目的是改变元素的顺序使之随机排序。这种预处理步骤可在O(n)时间内运行。能够起到同样作用的另一种简单方法是在算法中引入一个随机元素,这可以通过随机地选择拆分元素的主元来实现。随机选择主元的结果放宽了关于输入元素的所有排列的可能性相同的步骤。引入这一步来修正原先的快速排序,可得到下面所示的随机化快速排序。新算法只是在区间[low…high]中一致随机地选择一个索引v,并将A[v]和A[low]交换,然后按照原来的快速排序算法继续。这里,parseInt(Math.random()*(high-low+1)
+
low)返回一个在low和high之间的数。
复制代码
代码如下:
/****************************************
算法:split
输入:数组A[low...high]
输出:
1.若有必要,输出按上述描述的重新排列的数组A;
2.划分元素A[low]的新位置w;
****************************************/
function
split(array,
low,
high)
{
var
i
=
low;
var
x
=
array[low];
for(var
j
=
low
+
1;
j
<=
high;
j++)
{
if(array[j]
<=
x)
{
i
++;
if(i
!=
j)
{
var
temp
=
array[i];
array[i]
=
array[j];
array[j]
=
temp;
}
}
}
temp
=
array[low];
array[low]
=
array[i];
array[i]
=
temp;
return
i;
}
/****************************************
算法:rquicksort
输入:A[0...n-1]
输出:按非降序排列数组A[0...n-1]
rquicksort(A,
0,
n-1);
****************************************/
function
rquicksort(array,
low,
high)
{
if(low
<
high)
{
/******随机化拆分元素的主元*******/
var
v
=
parseInt(Math.random()*(high-low+1)
+
low);
var
tmp
=
array[low];
array[low]
=
array[v];
array[v]
=
tmp;
/******随机化拆分元素的主元*******/
var
w
=
split(array,
low,
high);
rquicksort(array,
low,
w
-1);
rquicksort(array,
w
+1,
high);
return
array;
}
}
var
array
=
[33,
22,
11,
88,
23,
32];
array
=
rquicksort(array,
0,
array.length-1);
console.log(array);
⑵ 快速排序的原理是什么
先
数据序列
选
元素,并
序列
所
比该元素
元素都放
右边或左边,再
左右两边
别用同
处
直
每
待处理
序列
度
1,
处理结束
前
序区R[1..H]
任取
数据元素作
比较
"基准"(
妨记
X)
用
基准
前
序区划
左右两
较
序区:R[1..I-1]
R[I+1..H]
且左边
序
区
数据元素均
于等于基准元素
右边
序
区
数据元素均
于等于基准元素
基准X则位于
终排序
位置
即R[1..I-1]≤X.Key≤R[I+1..H](1≤I≤H)
R[1..I-1]
R[I+1..H]均非空
别
进行
述
划
程
直至所
序
区
数据元素均已排序
止
快速排序
基本思想
基于
治策略
于输入
序列L[p..r]
规模足够
则直接进行排序(比
用前述
冒泡、选择、插入排序均
)
否则
三步处理:
解(Divide):
待排序列L[p..r]划
两
非空
序列L[p..q]
L[q+1..r]
使L[p..q]
任
元素
值
于L[q+1..r]
任
元素
值
具体
通
途径实现:
序列L[p..r]
选择数据元素L[q]
经比较
移
L[q]
处于L[p..r]
间
适
位置
使
数据元素L[q]
值
于L[q+1..r]
任
元素
值
递归求解(Conquer):通
递归调用快速排序算
别
L[p..q]
L[q+1..r]进行排序
合并(Merge):由于
解
两
序列
排序
进行
所
L[p..q]
L[q+1..r]都排
序
需要执行任何计算L[p..r]
已排
序
即自
合并
解决流程
符合
治
基本步骤
快速排序
治
经典应用实例
⑶ 快速排序法的平均时间复杂度和最坏时间复杂度分别是多少
快速排序的平均时间复杂度和最坏时间复杂度分别是O(nlgn)、O(n^2)。
当排序已经成为基本有序状态时,快速排序退化为O(n^2),一般情况下,排序为指数复杂度。
快速排序最差情况递归调用栈高度O(n),平均情况递归调用栈高度O(logn),而不管哪种情况栈的每一层处理时间都是O(n),所以,平均情况(最佳情况也是平均情况)的时间复杂度O(nlogn),最差情况的时间复杂度为O(n^2)。
(3)js快速排序算法扩展阅读
快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序,它采用了一种分治的策略,通常称其为分治法。快速排序算法通过多次比较和交换来实现排序,其排序流程如下:
(1)首先设定一个分界值,通过该分界值将数组分成左右两部分。
(2)将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值。
(3)然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。
(4)重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。
⑷ JS中的各种排序方法
数据结构算法中排序有很多种,常见的、不常见的,至少包含十种以上。根据它们的特性,可以大致分为两种类型:比较类排序和非比较类排序
冒泡排序是一次比较两个元素,如果顺序是错误的就把它们交换过来。,直到不需要再交换
快速排序的基本思想是通过一趟排序,将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可以分别对这两部分记录继续进行排序,以达到整个序列有序
从数列中挑出一个元素,称为 “基准”(pivot);然后重新排序数列,所有元素比基准值小的摆放在基准前面、比基准值大的摆在基准的后面;在这个区分搞定之后,该基准就处于数列的中间位置;然后把小于基准值元素的子数列(left)和大于基准值元素的子数列(right)递归地调用 quick 方法排序完成,这就是快排的思路
通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入,从而达到排序的效果
插入排序的思路是基于数组本身进行调整的,首先循环遍历从 i 等于 1 开始,拿到当前的 current 的值,去和前面的值比较,如果前面的大于当前的值,就把前面的值和当前的那个值进行交换,通过这样不断循环达到了排序的目的
将最小的元素存放在序列的起始位置,再从剩余未排序元素中继续寻找最小元素,然后放到已排序的序列后面……以此类推,直到所有元素均排序完毕
堆排序是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质,即子结点的键值或索引总是小于(或者大于)它的父节点。堆的底层实际上就是一棵完全二叉树,可以用数组实现
归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并
通过 mid 可以把该数组分成左右两个数组,分别对这两个进行递归调用排序方法,最后将两个数组按照顺序归并起来