Javascript算法系列之快速排序(Quicksort)
2014-02-08 09:33
633 查看
原文出自:
http://www.nczonline.net/blog/2012/11/27/computer-science-in-javascript-quicksort/
https://gist.github.com/paullewis/1981455#file-gistfile1-js
快速排序(Quicksort)是对冒泡排序的一种改进,是一种分而治之算法归并排序的风格
核心的思想就是通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列
理论上的步骤:
找到一个“支点”项目在数组中,可以是中心点,基准
在阵列中的第一项开始指针(左指针)。
在数组中的最后一个项目开始一个指针(右指针)。
而在左指针数组中的值小于枢轴值,将左指针向右(加1)。 继续,直到在左指针的值大于或等于所述枢轴值。
而在合适的指针数组中的值大于枢轴值,将右指针向左(减去1)。 继续下去,直到在正确的指针的值小于或等于所述枢轴值。
如果左指针是小于或等于右指针,然后交换的值在数组中的这些位置。
移动左指针向右由1和右指针向左之一。
如果左指针和右指针不符合,请转到步骤1。
原文太罗嗦了,简单的来说
在数据集之中,选择一个元素作为"基准"(pivot)。
所有小于"基准"的元素,都移到"基准"的左边;所有大于"基准"的元素,都移到"基准"的右边。
对"基准"左边和右边的两个子集,不断重复第一步和第二步,直到所有子集只剩下一个元素为止。
来个实际的demo
具体的流程算法如下:
针对这一组数组,如何选择这个支点呢,有些算法选择第一项为支点, 这是不是最好的选择,性能最差。 一般更好地选择数组中间的支点,所以考虑5是枢轴值(数组的长度除以2)
接下来从左边拿0位置拿第一个数与支点5对比,如果4<5,那么指针的位置就偏移到1,然后2<5,一次类推
如果6>5的时候,此时左边的指针就停止移动
然后从右边的指针开始移动,也是如此,只是右边是取的大于的值,比如9>5 ,往前移位,3<5,此时也停止移动,然后交换指针对应的数值
第一步:选择支点
第二步: 指针在前后开始偏移
第三步:如果4<5,继续移动左边的指针往下
第四步:如果2<5,往下,6>5停止
第五步:9>5,往前,3<5停止
第六步:交换指针指向的值
第七步:继续如上的操作,直到支点
第八部:如果指针到了支点,就停止
配合实现交换的swap的代码
实现的代码
这个函数接受三个参数:
整个算法是循环只是一个循环。 外环确定何时所有的数组范围的项目已经被处理。 左,右指针的两个内部循环控制运动。当两个内部循环的完成,则该指针进行比较,以确定是否交换是必要的。 在交换之后,两个指针被移动,使外循环继续,在合适的地方。 该函数返回的左指针的值,因为这是用于确定从哪里开始隔间的下一次。 请记住,该分区是发生在地方,而不会产生任何额外的数组。
快速排序算法基本上通过划分整个阵列的工作原理,然后递归地分割阵列的左侧和右侧的部分,直到整个阵列被排序。
在前面的例子中,数组变
如下面的图所示
第一步:找到指针遍历的位置,确定支点
第二步:从左右指针位置开始,对比4<3,停止
第三步:因为5>3,移动右边的指针,因为3==3,停止
第四步:交换指针指向的值
第五步:依次如上处理
第六步:因为2<3,移动左边指针,因为4>3,停止
因为左边的指针超过了右边的指针,停止
该过程之后,该阵列变成
快速排序通常被认为是高效,快速等特点是使用V8引擎的实现
归并排序是快速排序的竞争对手,因为它也是高效,快捷,但有被稳定的好处。 这就是为什么Mozilla和Safari中使用它自己的执行
http://www.nczonline.net/blog/2012/11/27/computer-science-in-javascript-quicksort/
https://gist.github.com/paullewis/1981455#file-gistfile1-js
快速排序(Quicksort)是对冒泡排序的一种改进,是一种分而治之算法归并排序的风格
核心的思想就是通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列
理论上的步骤:
找到一个“支点”项目在数组中,可以是中心点,基准
在阵列中的第一项开始指针(左指针)。
在数组中的最后一个项目开始一个指针(右指针)。
而在左指针数组中的值小于枢轴值,将左指针向右(加1)。 继续,直到在左指针的值大于或等于所述枢轴值。
而在合适的指针数组中的值大于枢轴值,将右指针向左(减去1)。 继续下去,直到在正确的指针的值小于或等于所述枢轴值。
如果左指针是小于或等于右指针,然后交换的值在数组中的这些位置。
移动左指针向右由1和右指针向左之一。
如果左指针和右指针不符合,请转到步骤1。
原文太罗嗦了,简单的来说
在数据集之中,选择一个元素作为"基准"(pivot)。
所有小于"基准"的元素,都移到"基准"的左边;所有大于"基准"的元素,都移到"基准"的右边。
对"基准"左边和右边的两个子集,不断重复第一步和第二步,直到所有子集只剩下一个元素为止。
来个实际的demo
var items = [4, 2, 6, 5, 3, 9];
具体的流程算法如下:
针对这一组数组,如何选择这个支点呢,有些算法选择第一项为支点, 这是不是最好的选择,性能最差。 一般更好地选择数组中间的支点,所以考虑5是枢轴值(数组的长度除以2)
接下来从左边拿0位置拿第一个数与支点5对比,如果4<5,那么指针的位置就偏移到1,然后2<5,一次类推
如果6>5的时候,此时左边的指针就停止移动
然后从右边的指针开始移动,也是如此,只是右边是取的大于的值,比如9>5 ,往前移位,3<5,此时也停止移动,然后交换指针对应的数值
第一步:选择支点
第二步: 指针在前后开始偏移
第三步:如果4<5,继续移动左边的指针往下
第四步:如果2<5,往下,6>5停止
第五步:9>5,往前,3<5停止
第六步:交换指针指向的值
第七步:继续如上的操作,直到支点
第八部:如果指针到了支点,就停止
配合实现交换的swap的代码
function swap(items, firstIndex, secondIndex){ var temp = items[firstIndex]; items[firstIndex] = items[secondIndex]; items[secondIndex] = temp; }
实现的代码
function partition(items, left, right) { var pivot = items[Math.floor((right + left) / 2)], i = left, j = right; while (i <= j) { while (items[i] < pivot) { i++; } while (items[j] > pivot) { j--; } if (i <= j) { swap(items, i, j); i++; j--; } } return i; }
这个函数接受三个参数:
items,这是值进行排序的阵列,
left,这是该指数以启动左指针时,和
right,这是该指数以启动右指针。 枢轴值是通过将所确定的
left和
right的值,然后除以2。 因为这个值可能是一个浮点数,有必要进行一些舍入。
整个算法是循环只是一个循环。 外环确定何时所有的数组范围的项目已经被处理。 左,右指针的两个内部循环控制运动。当两个内部循环的完成,则该指针进行比较,以确定是否交换是必要的。 在交换之后,两个指针被移动,使外循环继续,在合适的地方。 该函数返回的左指针的值,因为这是用于确定从哪里开始隔间的下一次。 请记住,该分区是发生在地方,而不会产生任何额外的数组。
快速排序算法基本上通过划分整个阵列的工作原理,然后递归地分割阵列的左侧和右侧的部分,直到整个阵列被排序。
在前面的例子中,数组变
[4, 2, 3, 5, 6, 9]一个分区,并返回索引后为4(左指针的最后一个席位),开始递归左右2个分割阵列
如下面的图所示
第一步:找到指针遍历的位置,确定支点
第二步:从左右指针位置开始,对比4<3,停止
第三步:因为5>3,移动右边的指针,因为3==3,停止
第四步:交换指针指向的值
第五步:依次如上处理
第六步:因为2<3,移动左边指针,因为4>3,停止
因为左边的指针超过了右边的指针,停止
该过程之后,该阵列变成
[3, 2, 4, 5, 6, 9]和返回的索引是1,继续这样,直到所有的阵列左侧的排序。 然后相同的处理接着在右侧的阵列。 基本对数的快速排序,然后变得非常简单:
function quickSort(items, left, right) { var index; if (items.length > 1) { index = partition(items, left, right); if (left < index - 1) { quickSort(items, left, index - 1); } if (index < right) { quickSort(items, index, right); } } return items; } // first call var result = quickSort(items, 0, items.length - 1);
快速排序通常被认为是高效,快速等特点是使用V8引擎的实现
Array.prototype.sort()上有超过23个项目的数组。 对于少于23个项目,V8采用插入排序法[2]。
归并排序是快速排序的竞争对手,因为它也是高效,快捷,但有被稳定的好处。 这就是为什么Mozilla和Safari中使用它自己的执行
Array.prototype.sort()
相关文章推荐
- jsp常用指令、基本动作和9种内置对象
- 10款优秀的JavaScript音频开发库
- 开发者不容错过的12款开源JavaScript库
- jsp中如何避免客户端浏览器在刷新时,使用缓存的数据
- JavaScript的strict模式与with关键字介绍
- 开发者必备的12个JavaScript库
- 网易前端JavaScript编码规范
- 【JS】js高级特性备忘
- jsp防止跨域提交数据的具体实现
- JavaScript的strict模式与with关键字介绍
- js数字转换为float,取N位小数
- 纯JS实现动态时间显示代码
- javascript中match函数的用法小结
- javascript中的self和this用法小结
- js控制分页打印、打印分页示例
- JS的参数传递示例介绍
- javascript类型转换使用方法
- 关于js中e = e || window.event写法说明
- JS面向对象继承实现
- javascript滚动新闻代码