分治算法之快速排序
2014-03-10 19:58
204 查看
快速排序是对冒泡排序的一种改进。基本思想是每次排序将序列分为两部分,每一部分的数据都比另一部分的数据要小,即取序列中的某个值为中间值,第一个子序列中每一个数据的值都比这个中间值小,第二个序列中每一个数据的值都比这个中间值大。然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
时间复杂度:平均O(nlogn) 。最坏情况O(n^2) 。
需要注意的是快速排序是一个不稳定的排序方法,但在大多数情况下时间复杂度是十分理想的。当出现多个重复值,或给定序列是有序的时候,时间复杂度是趋近于n^2。
快速排序同时也是一种分治思想的体现
回顾一下
step1 分解:将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题;
step2 解决:若子问题规模较小而容易被解决则直接解,否则递归地解各个子问题
step3 合并:将各个子问题的解合并为原问题的解。
1.选择杠杆点也就是分界线
2.分解 把序列分解成两个子序列
3.两个序列分别再继续进行快速排序
4.合并 两个子序列合并为大序列
通过源代码来体现
曾经令我疑惑的一点就是怎么确定分界线左边的小于,,分界线的右边大呢,,怎么多次交换好不好,乱了怎么办,
笔者数学不好只能形式上的分析一下,
1.开始先判断右边的,出现小的就跳出第一个while循环 然后赋值,第一次覆盖了杠杆点,这样实际上此时数字中有两个重复值了
2.然后判断左边的,出现大的也跳出循环,第二次覆盖了之前有两个副本中的那个
3.周尔复始 最后的临界值属于中间的那个多出一个副本的位置了
这种算法的缺陷也很明显,当数字序列式顺序的时候或者一些特殊情况的时候,序列可能出现由n拆成 1,n-1的情况,
下面给出一个一种改进算法
时间复杂度:平均O(nlogn) 。最坏情况O(n^2) 。
需要注意的是快速排序是一个不稳定的排序方法,但在大多数情况下时间复杂度是十分理想的。当出现多个重复值,或给定序列是有序的时候,时间复杂度是趋近于n^2。
快速排序同时也是一种分治思想的体现
回顾一下
step1 分解:将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题;
step2 解决:若子问题规模较小而容易被解决则直接解,否则递归地解各个子问题
step3 合并:将各个子问题的解合并为原问题的解。
1.选择杠杆点也就是分界线
2.分解 把序列分解成两个子序列
3.两个序列分别再继续进行快速排序
4.合并 两个子序列合并为大序列
通过源代码来体现
package org.quicksort; public class QuickSort { public static void QuickSort(int[] array, int i, int j) { if (i < j) { int q = partiton(array, i, j); QuickSort(array, i, q - 1); QuickSort(array, q + 1, j); } } public static int partiton(int[] array, int n, int m) { array[0] = array ; int t; while (m > n) { while (m > n && array[0] <array[m]) { m--; } array = array[m]; while (m > n && array[0] > array ) { n++; } array[m] = array ; } array[m]=array[0]; return m; } public static void main(String args[]) { int array[]={0,33,20,55,44,13,22,43,23,21,21,52}; QuickSort.QuickSort(array, 1, 11); for(int i=1;i<array.length;i++) { System.out.println(array[i]); } } }
曾经令我疑惑的一点就是怎么确定分界线左边的小于,,分界线的右边大呢,,怎么多次交换好不好,乱了怎么办,
笔者数学不好只能形式上的分析一下,
1.开始先判断右边的,出现小的就跳出第一个while循环 然后赋值,第一次覆盖了杠杆点,这样实际上此时数字中有两个重复值了
2.然后判断左边的,出现大的也跳出循环,第二次覆盖了之前有两个副本中的那个
3.周尔复始 最后的临界值属于中间的那个多出一个副本的位置了
这种算法的缺陷也很明显,当数字序列式顺序的时候或者一些特殊情况的时候,序列可能出现由n拆成 1,n-1的情况,
下面给出一个一种改进算法
package org.quicksort; public class Quick1Sort { public static void QuickSort(int[] array, int i, int j) { if (i < j) { int q = partiton(array, i, j); QuickSort(array, i, q - 1); QuickSort(array, q + 1, j); } } public static int partiton(int[] array, int n, int m) { array[0] = (array +array[m])/2; int t; while (m > n) { while (m > n && array[0] < array[m]) { m--; } while (m > n && array[0] > array ) { n++; } t=array[m]; array[m] = array ; array =t; } return m; } public static void main(String args[]) { int array[]={0,33,20,55,44,13,22,43,23,21,100,52}; Quick1Sort.QuickSort(array, 1, 11); for(int i=1;i<array.length;i++) { System.out.println(array[i]); } } }
相关文章推荐
- 分治算法之快速排序
- 算法(分治)合并排序和快速排序
- 分治算法之快速排序
- 算法之分治思想和快速排序
- 算法--排序--分治与快速排序
- 经典算法4:分治法求解快速排序
- <菜鸟学算法-A排序(分治的思想:快速排序)>
- 算法基础(3)分治策略之快速排序
- 分治算法之快速排序
- 数对之差的最大值[算法]-分治法
- 排序算法之快速排序
- 算法——快速排序(Quicksort)
- 从三色旗算法到快速排序
- 算法知识点整理——第2章 递归与分治策略
- php算法之快速排序
- Algorithm: quick sort implemented in python 算法导论 快速排序
- 经典排序算法之快速排序
- 常用算法之分治法与动态规划法
- 算法-归并排序(分治)
- 内部排序冒泡排序、插入排序、选择排序、快速排序的算法和PHP实现