快速排序--java版本
快速排序法介绍:
快速排序(Quicksort)是对冒泡排序的一种改进。基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。快速排序由于排序效率在同为O(N*logN)的几种排序方法中效率较高,因此经常被采用,再加上快速排序思想----分治法也确实实用。
该方法的基本思想是:
1.先从数列中取出一个数作为基准数。
2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
3.再对左右区间重复第二步,直到各区间只有一个数。
这排序有两种方法:
- 以一个数组的中间数为中轴pivot=arr[(left+right)/2],左边left从小到大找到一个比pivot大的数,在在right边找到个比pivot小的数,这左右边都跳出这轮循环,并交换两边的数据,在重复上面的操作。到排完一轮,在对左右重复上面直到所有的排序完。
- 以数组第一个数为中轴pivot,先从最右边从大到小,找到一个小于pivot的数,交换让这个数填充pivot,在从左边开始在找个大于pivot的数,又与pivot交换,填充,一直重复下去。
方法一的解释:
这个中轴数可以取数组中间。
代码如下:
[code]package com.atguigu.sort; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; public class QuickSort { public static void main(String[] args) { int[] arr = {-9,78,0,23,-567,70, -1,900, 4561}; quickSort(arr, 0, arr.length-1); System.out.println("arr=" + Arrays.toString(arr)); } public static void quickSort(int[] arr,int left, int right) { int l = left; //左下标 int r = right; //右下标 //pivot 中轴值 int pivot = arr[(left + right) / 2]; int temp = 0; //临时变量,作为交换时使用 //while循环的目的是让比pivot 值小放到左边 //比pivot 值大放到右边 while( l < r) { //在pivot的左边一直找,找到大于等于pivot值,才退出 while( arr[l] < pivot) { l += 1; } //在pivot的右边一直找,找到小于等于pivot值,才退出 while(arr[r] > pivot) { r -= 1; } //如果l >= r说明pivot 的左右两的值,已经按照左边全部是 //小于等于pivot值,右边全部是大于等于pivot值 if( l >= r) { break; } //交换 temp = arr[l]; arr[l] = arr[r]; arr[r] = temp; //如果交换完后,发现这个arr[l] == pivot值 相等 r--, 前移 if(arr[l] == pivot) { r -= 1; } //如果交换完后,发现这个arr[r] == pivot值 相等 l++, 后移 if(arr[r] == pivot) { l += 1; } } // 如果 l == r, 必须l++, r--, 否则为出现栈溢出 if (l == r) { l += 1; r -= 1; } //向左递归 if(left < r) { quickSort(arr, left, r); } //向右递归 if(right > l) { quickSort(arr, l, right); } } }
方法二求解:
此方法参考了morewindows博主大佬的博客整理的下面的方法。
以一个数组作为示例,取区间第一个数为基准数。
初始时,i = 0; j = 9; X = a[i] = 72
由于已经将a[0]中的数保存到X中,可以理解成在数组a[0]上挖了个坑,可以将其它数据填充到这来。
从j开始向前找一个比X小或等于X的数。当j=8,符合条件,将a[8]挖出再填到上一个坑a[0]中。a[0]=a[8]; i++; 这样一个坑a[0]就被搞定了,但又形成了一个新坑a[8],这怎么办了?简单,再找数字来填a[8]这个坑。这次从i开始向后找一个大于X的数,当i=3,符合条件,将a[3]挖出再填到上一个坑中a[8]=a[3]; j--;
数组变为:
i = 3; j = 7; X=72
再重复上面的步骤,先从后向前找,再从前向后找。
从j开始向前找,当j=5,符合条件,将a[5]挖出填到上一个坑中,a[3] = a[5]; i++;
从i开始向后找,当i=5时,由于i==j退出。
此时,i = j = 5,而a[5]刚好又是上次挖的坑,因此将X填入a[5]。
数组变为:
可以看出a[5]前面的数字都小于它,a[5]后面的数字都大于它。因此再对a[0…4]和a[6…9]这二个子区间重复上述步骤就可以了。
对填充进行总结
1.i =L; j = R; 将基准数挖出形成第一个坑a[i]。
2.j--由后向前找比它小的数,找到后挖出此数填前一个坑a[i]中。
3.i++由前向后找比它大的数,找到后也挖出此数填到前一个坑a[j]中。
4.再重复执行2,3二步,直到i==j,将基准数填入a[i]中。
[code]package com.atguigu.sort; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; public class QuickSort { public static void main(String[] args) { int[] arr = {-9,78,0,23,-567,70, -1,900, 4561}; quick_sort(arr, 0, arr.length-1); System.out.println("arr=" + Arrays.toString(arr)); } //快速排序 void quick_sort(int s[], int l, int r) { if (l < r) { //Swap(s[l], s[(l + r) / 2]); //将中间的这个数和第一个数交换 参见注1 int i = l, j = r, x = s[l]; while (i < j) { while(i < j && s[j] >= x){ // 从右向左找第一个小于x的数 j--; } if(i < j) { s[i++] = s[j]; } while(i < j && s[i] < x){ // 从左向右找第一个大于等于x的数 i++; } if(i < j) { s[j--] = s[i]; } } s[i] = x; quick_sort(s, l, i - 1); // 递归调用 quick_sort(s, i + 1, r); } } }
- 快速排序 python从java版本翻译过来:
- 各种常见的排序 java版本(冒泡,选择,插入,希尔,快速)
- 快速排序 --Java版本
- 【算法】快速排序-Java版本
- 快速排序的java版本
- Java 冒泡排序、选择排序、快速排序、归并排序
- 排序算法之快速排序java实现
- 快速排序的java实现
- java快速排序
- 算法导论 第2版 7.3 快速排序随机化版本
- 快速排序方法Java实现与分析
- java实现快速排序-递归
- Java 实现 堆排序 快速排序 以及 TopK问题(一)
- [排序算法]--快速排序的Java实现
- Java数据结构与算法:快速排序
- JAVA简单排序之快速排序
- java 希尔排序 归并排序 快速排序 三路快速排序
- 快速排序【JAVA实现】
- 关于Web快速开发平台ES2007java版本的DataCenter功能(导出)
- Java实现快速排序