js快速排序算法解析
数组的快速排序算法,和并归排序步骤基本类似。
都是先拆分,后合并。并归排序是:拆分容易,合并难。 快速排序是:拆分难,合并容易
要理解快速排序,首先要理解拆分逻辑
要素:找一个基准点,通过操作使得数列的左边全部都是小于他的数,右边全部都是大于他的数;
1、选中基准点,开始索引 i ,结束索引 j
2、从数列右边开始往左边找,找到比基准点小的,交换位置 i++
3、从数列左边开始往右边找,找到比基准点大的,交换位置 j--
4、循环执行2、3,直到,i 不是小于 j
例如: 有数组 var arr = [30,24,5,58,18,36,12,42,39];
开始索引 i = 0; 结束索引 j = arr.length-1; 基准点 pivot = arr[i] 即为30
则有如下代码
var arr = [30,24,5,58,18,36,12,42,39];
var i = 0, j = arr.length-1,pivot = arr[i]; while(i < j ){ //当最后结束时 i = j
//从右往左找,找到比基准点小等的就交换,交换后,基准点的索引变为 j
while(i < j && arr[j] > pivot )
j--; //排除已经满足条件的点
if(i < j ){
swap(i++,j,arr);
} //从左往右找,找到比基准点大的就交换,交换后,基准点的索引变为 i
while(i < j && arr[i] <= pivot)
i++; //排除已经满足条件的点
if(i < j ){
swap(i,j--,arr);
}
} function swap(a,b,arr){
console.log(a,b,arr[a],arr[b])
var temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
} console.log(i,arr); //基准点i,处理好的arr
以上代码就是快速排序的核心,如果将数列,不断以上面方式细分,直到分为单个元素。即最后的结果就是一个有序的数列
下面给出完整代码
var arr = [30,24,5,58,18,36,12,42,39];
function Partition(arr,low,high){
var i = low,j = high,pivot = arr[i];
while(i < j ){
//从右往左找
while(i < j && arr[j] > pivot )
j--;
if(i < j ){
swap(i++,j,arr);
}
//从左往右找
while(i < j && arr[i] <= pivot)
i++;
if(i < j ){
swap(i,j--,arr);
}
}
return i; //返回基准元素位置
}
function swap(a,b,arr){
console.log(a,b,arr[a],arr[b])
var temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
function QuickSort(arr,low,high){
var mid;
if(low < high){
mid = Partition(arr,low,high); //返回基准元素位置
QuickSort(arr,low,mid-1); //左边快速排序
QuickSort(arr,mid+1,high); //右边快速排序
}
}
QuickSort(arr,0,arr.length-1);
console.log(arr);
优化扩展:
上面的Partition函数中,不管是从右往左,还是从左往右。都是跟pivot基准元素交换。。实际上,可以先直接左边和右边交换,最后再和基准元素交换,减少交换次数。代码如下
var arr = [30,24,5,58,18,36,12,42,39];
var i = 0, j = arr.length-1,pivot = arr[i];
var mid;
while(i < j ){ //当最后结束时 i = j
//从右往左找
while(i < j && arr[j] > pivot )
j--; //排除已经满足条件的点
//从左往右找
while(i < j && arr[i] <= pivot)
i++; //排除已经满足条件的点 //找到两个点,就相互交换
if(i < j ){
swap(i++,j--,arr);
}
} //最后将中间点和基准点交换
if(arr[i] > pivot){
mid = i-1;
swap(0,mid,arr);
}else{
mid = i;
swap(0,mid,arr);
} function swap(a,b,arr){
console.log(a,b,arr[a],arr[b])
var temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
} console.log(mid,arr); //基准点mid,处理好的arr
使用js的数组方法 , unshift 和push
使用unshift 和push实现,将数列的基准元素,左边全部小于他,右边全部大于他
var arr = [30,24,5,58,18,36,12,42,39];
var i = 0, pivot = arr[0], arr2 = [pivot];
for(var j = 1; j < arr.length; j++ ){
if(arr[j] > pivot){
arr2.push(arr[j]);
}else{
arr2.unshift(arr[j]);
i++;
}
}
console.log(i,arr2);
使用 unshift和push实现的快速排序
var arr = [30,24,5,58,18,36,12,42,39];
function Partition(arr,low,high){
var i = low,pivot = arr[i];
var arr2 = [pivot];
for(var j = low+1; j <= high; j++){
if(arr[j] > pivot){
arr2.push(arr[j]);
}else{
arr2.unshift(arr[j]);
i++;
}
}
j = 0;
for(var k = low ; k <= high ; k++){
arr[k] = arr2[j++];
}
return i; //返回基准元素位置
}
function QuickSort(arr,low,high){
var mid;
if(low < high){
mid = Partition(arr,low,high); //返回基准元素位置
QuickSort(arr,low,mid-1); //左边快速排序
QuickSort(arr,mid+1,high); //右边快速排序
}
}
QuickSort(arr,0,arr.length-1);
console.log(arr);
js快速排序算法解析的更多相关文章
- js快速排序算法
真正的快速排序算法一: function quickSort(array){ function sort(prev, numsize){ var nonius = prev; var j = nums ...
- js 快速排序算法
Array.prototype.quickSort = function() { var len = this.length; if(len < 2) return this; var left ...
- 结构-行为-样式-Js排序算法之 快速排序
快速排序算法,是我的算法系列博客中的第二个Js实现的算法,主要思路: 在一个数组中随机取一个数(一般都取第一个或者最后一个),使这个数与数组中其他数进行比较,如果比它大就放到它的右边,比它小就放 ...
- js排序算法05——快速排序
终于到了传说中的快速排序算法了,快速排序的思想和归并排序一样,都是采用分治思想,不同之处在于归并每次将数组一分为二,最后将小的数组进行比较,合并为大数组.快排是每次找一个主元,也就是基准数,按照这个基 ...
- Peterson算法与Dekker算法解析
进来Bear正在学习巩固并行的基础知识,所以写下这篇基础的有关并行算法的文章. 在讲述两个算法之前,需要明确一些概念性的问题, Race Condition(竞争条件),Situations lik ...
- python常见排序算法解析
python——常见排序算法解析 算法是程序员的灵魂. 下面的博文是我整理的感觉还不错的算法实现 原理的理解是最重要的,我会常回来看看,并坚持每天刷leetcode 本篇主要实现九(八)大排序算法 ...
- Learn Algorithms With Javascript - 基于 Js 进行算法学习
基于 javascript 学习并实现常用的经典算法,欢迎对算法和数学感兴趣的 Js 开发者参与,一起学习共同进步. 算法实现 排序 插入排序 sort/lib/insertion-sort.js 希 ...
- Js常见算法实现汇总
/*去重*/ <script> function delRepeat(arr){ var newArray=new Array(); var len=arr.length; for(var ...
- 总结下js排序算法和乱序算法
其实本人最怕的就是算法,大学算法课就感觉老师在讲天书,而且对于前端来说,算法在实际的应用中实在是很有限.毕竟算法要依靠大量的数据为基础才能发挥出算法的效率,就浏览器那性能,......是吧,退一万步说 ...
随机推荐
- hdu3613 Best Reward【Manacher】
Best Reward Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total ...
- 2018ACM-ICPC焦作区域赛【反思总结】
摸银结束回来,整个人都轻松了. 自CCPC打铁以来的这两个月真的太痛苦了. 俱乐部退役的退役停训的停训,好冷清啊. 前期切题很稳,前四题两个小时1A. 过了四题之后好像心态有点飘,然后开题就慢了,想题 ...
- hdu2609 How many【最小表示法】【Hash】
How many Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- FileZilla:425 Can't open data connection for transfer of解决办法
状况描述: 服务器端采用的Windows 2008系统,安装了FileZilla Server,客户端采用的FileZilla Client,客户端在连接服务器端的时候,可以正常通过验证,但是在列出目 ...
- [No0000178]改善C#程序的建议1:非用ICloneable不可的理由
好吧,我承认,这是一个反标题,实际的情况是:我找不到一个非用ICloneable不可的理由.事实上,接口ICloneable还会带来误解,因为它只有一个Clone方法. 我们都知道,对象的拷贝分为:浅 ...
- [No000011A]Office Excel设置显示日期与星期
设置excel日期格式,自定义,yyyy-mm-dd 上午/下午 hh:mm:ss AM/PM dddd aaaa
- 关于字符串的简单dp
看这道题题目叫做魔族密码多新奇的名字点开是道字符串的dp,思考然后想出lis其实但字符串之间的比对只有循环然后其实循环爆不了,太懒点开了题解发现有人使用stl——cstring的函数了方便多了,借鉴一 ...
- Delphi中DLL初始化和退出处理
来自delphibbs: zhousy_2000, 时间: 2005-09-13 13:53:00, ID: 3203484 <1>利用Unit的Initalization与Finaliz ...
- python,re模块正则
python没有正则需要导入re模块调用.正则表达式是为了匹配字符串,动态模糊的匹配,只要有返回就匹配到了, 没返回就没匹配到,前面是格式后面是字符串 最常用的匹配语法: re.match()#麦驰, ...
- Orchard Core 自定义权限配置
在我们为Orchard Core配置了一个新的Module之后,我们要考虑的是谁可以访问这个Module,那么这里就涉及到了一个权限的配置.如下图,添加了自定义的权限: Orchard Core源码: ...