排序-快速排序
2016-11-24 11:42
155 查看
快速排序:
快速排序是最流行的排序算法,在大多数情况下,快速排序都是最快的,执行时间为O(N*logN)级。
快速排序算法本质上通过把一个数组划分为两个子数组,然后递归调用自身为每一个子数组进行快速排序实现的。
快速排序有三个基本的步骤:
1.把数组或者子数组分成左边(较小的关键字)的一组和右边(较大的关键字)的一组
2.调用自身对左边进行排序
3.再次调用自身对右边的一组进行排序。
经过一次划分之后,所有在左边子数组的数据项都小于在右边子数组的数据项,只要对左边子数组和右边子数组分别进行排序,整个数组就是有序的了,也通过递归调用排序算法自身就可以。
传递给recQuickSort()方法的参数决定了要排序数组的左右两端位置,这个方法首先检查数组是否只包含一个数据项,如果数组只包含一个数据项,那么就定义数组已经有序,方法立即返回,这就是递归的基值条件(递归的出口)。
如果数组包含两个或者更多的数据项,算法就调用partitionIt()方法对数组进行划分。方法返回分隔边界的下标数值(partition),它指向右边(较大关键字)z子数组最左端的数据项。
对数组进行划分之后,recQuickSort()递归的调用自身,数组左边的部分调用一次,对从left到partition-1位置上的数据项进行排序,数组右边的部分也调用一次,对从partition到right位置上的数据项进行排序。注意这两个递归都不包含数组下标为partition的数据项,为什么呢?原因在于轴值(枢纽)的选择
选择轴值:partitionIt()方法应该使用什么样的轴值呢,下面是一些相关的想法:
–应该选择具体的一个数据项的关键字的值作为轴值,这个数据项称为pivot(轴值)
–可以选择任意一个数据项作为轴值。为了简便,我们总是假设总是选择待划分的子数组的最右端的数据项作为轴值
—划分完成之后,如果轴值插到左右子数组之间的分界处,那么轴值就落在排序之后的最终位置上。
为了实现把把轴值放入正确位置的操作,只要交换轴值和右边子数组的最左端的数据项就可以了。这个交换操作把轴值放在了正确的位置上,也就是左右子数组之间
完整代码:
快速排序是最流行的排序算法,在大多数情况下,快速排序都是最快的,执行时间为O(N*logN)级。
快速排序算法本质上通过把一个数组划分为两个子数组,然后递归调用自身为每一个子数组进行快速排序实现的。
快速排序有三个基本的步骤:
1.把数组或者子数组分成左边(较小的关键字)的一组和右边(较大的关键字)的一组
2.调用自身对左边进行排序
3.再次调用自身对右边的一组进行排序。
经过一次划分之后,所有在左边子数组的数据项都小于在右边子数组的数据项,只要对左边子数组和右边子数组分别进行排序,整个数组就是有序的了,也通过递归调用排序算法自身就可以。
传递给recQuickSort()方法的参数决定了要排序数组的左右两端位置,这个方法首先检查数组是否只包含一个数据项,如果数组只包含一个数据项,那么就定义数组已经有序,方法立即返回,这就是递归的基值条件(递归的出口)。
如果数组包含两个或者更多的数据项,算法就调用partitionIt()方法对数组进行划分。方法返回分隔边界的下标数值(partition),它指向右边(较大关键字)z子数组最左端的数据项。
对数组进行划分之后,recQuickSort()递归的调用自身,数组左边的部分调用一次,对从left到partition-1位置上的数据项进行排序,数组右边的部分也调用一次,对从partition到right位置上的数据项进行排序。注意这两个递归都不包含数组下标为partition的数据项,为什么呢?原因在于轴值(枢纽)的选择
选择轴值:partitionIt()方法应该使用什么样的轴值呢,下面是一些相关的想法:
–应该选择具体的一个数据项的关键字的值作为轴值,这个数据项称为pivot(轴值)
–可以选择任意一个数据项作为轴值。为了简便,我们总是假设总是选择待划分的子数组的最右端的数据项作为轴值
—划分完成之后,如果轴值插到左右子数组之间的分界处,那么轴值就落在排序之后的最终位置上。
为了实现把把轴值放入正确位置的操作,只要交换轴值和右边子数组的最左端的数据项就可以了。这个交换操作把轴值放在了正确的位置上,也就是左右子数组之间
完整代码:
public class QuickSortTest { private int[] array; private int number; public QuickSortTest(int max) { array = new int[max]; number = 0; } public void insert(int value) { array[number] = value; number++; } public void display() { for (int i = 0; i < number; i++) { System.out.print(array[i]+" "); System.out.print(" "); } } public void quickSort() { recQuickSort(0, number-1); } //递归调用的方法 public void recQuickSort(int left,int right) { if(right -left <= 0) return; else { int pivot =array[right]; //选定最右边元素作为轴值 int partition = partitionIt(left, right, pivot); recQuickSort(left, partition-1); //递归,将左边的元素排序 recQuickSort(partition+1, right); //递归,将右边的元素排序 } } //分隔数组的方法 public int partitionIt(int left,int right,int pivot) { int leftPointer= left-1; //左指针 int rightPointer= right; //右指针 while(true) { //左指针移动,移动到下一个元素比轴值小 ,不用交换 //因为我们的目的是找到所有比轴值小的元素放在轴值左边,所有比轴值大的元素放在轴值右边 while(array[++leftPointer] < pivot); //右指针移动,移动到下一个元素如果比轴值大,不用交换 while(rightPointer>0 && array[rightPointer--]>pivot); //z左指针大于等于右指针,也就是两个指针相遇了,就停下来。 if(leftPointer >= rightPointer) break; else swap(leftPointer,rightPointer); } swap(leftPointer,right); //将轴值与左指针交换 return leftPointer; //返回轴值的位置 } //用于交换两个元素的方法 public void swap(int index1,int index2) { int temp =array[index1]; array[index1] = array[index2]; array[index2] = temp; } public static void main(String[] args) { int max=16; QuickSortTest array=new QuickSortTest(max); array.insert(76); array.insert(78); array.insert(78); array.insert(7); array.insert(8); array.insert(478); array.insert(728); array.quickSort(); array.display(); } }
相关文章推荐
- 无聊写排序之 ---- 快速排序(QuickSort) 非递归实现
- Java-冒泡排序、快速排序、插入排序、快速排序
- 算法基础之排序篇-快速排序
- <菜鸟学算法-A排序(分治的思想:快速排序)>
- 冒泡排序与选择排序的不同、快速排序与选择排序的结合
- 排序-快速排序
- 算法——排序之快速排序
- 排序算法之快速排序
- 八大排序——快速排序
- 交换排序_快速排序
- 易混的排序算法:冒泡排序、选择排序、快速排序
- 【排序】快速排序
- 数据结构实验之排序七:选课名单——快速排序
- 插入法排序、选择排序、冒泡法、快速排序、堆排序的C实现
- 算法6-排序-快速排序
- 【排序】快速排序
- 初级版、正宗版、升级版冒泡排序;简单选择排序;直接插入排序;希尔排序;堆排序;递归法 、非递归法归并排序;快速排序; 快速排序优化算法
- 数据排序谁最快(javascript中的Array.prototype.sort PK 快速排序)
- 排序系列之快速排序
- Java实现常见的排序算法之快排(快速排序)