如何提高java编程能力:谁能用java写一个“快速排序”呢?

算法(37)
java进阶(56)
编程(43)
数据结构(7)
八大排序算法(7)
五十道编程小算法(38)
快速排序算法介绍
& & & 快速排序和归并排序都使用分治法来设计算法,区别在于归并排序把数组分为两个基本等长的子数组,分别排好序之后还要进行归并(Merge)操作,而快速排序拆分子数组的时候显得更有艺术,取一个基准元素,拆分之后基准元素左边的元素都比基准元素小,右边的元素都不小于基准元素,这样只需要分别对两个子数组排序即可,不再像归并排序一样需要归并操作。
基本思想:
1)选择一个基准元素,通常选择第一个元素或者最后一个元素,
2)通过一趟排序讲待排序的记录分割成独立的两部分,其中一部分记录的元素值均比基准元素值小。另一部分记录的&元素值比基准值大。
3)此时基准元素在其排好序后的正确位置
4)然后分别对这两部分记录用同样的方法继续进行排序,直到整个序列有序。
快速排序的示例:
(a)一趟排序的过程:
(b)排序的全过程
算法的实现:
import java.util.R
public class QuickSort {
// 快速排序
private static void quickSort(int[] a) {
System.out.println(&在数组中从0到&+(a.length-1)+&基准元素索引:& + 0);
subQuickSort(a, 0, a.length-1);
private static void subQuickSort(int[] a,int start, int end) {
if(a == null || end-start&2){
int keyIndex = quickSortPortion(a, start, end);
System.out.println(&在数组中从&+start+&到&+end+&基准元素索引变换:& + keyIndex);
if(keyIndex == start){
subQuickSort(a, start+1, end);
}else if(keyIndex == end){
subQuickSort(a, start, end-1);
subQuickSort(a, start, keyIndex-1);
subQuickSort(a, keyIndex+1, end);
private static int quickSortPortion(int[] a, int start, int end) {
int minIndex = (end-start) / 2 + // minIndex定义为数组的中间索引
int key = // 将数组的第一个元素的索引定义为基准元素
System.out.println(&快速排序------------&&);
for (int i = i & i++) { // 比较 length-1次
if (key &= minIndex) { // 如果基准元素在前半部分
if (a[key] & a[h]) { // 元素值比基准元素值小
swap(a, key, h); // 交换位置
h = key + 1;
} else { // 如果基准元素在后半部分
if (a[key] & a[h]) { // 元素值比基准元素值大
swap(a, key, h); // 交换位置
h = tmp - 1;
// 交换数组元素
private static void swap(int[] arr, int i, int j) {
if (i == j) {
arr[i] = arr[i] + arr[j];
arr[j] = arr[i] - arr[j];
arr[i] = arr[i] - arr[j];
// 打印数组
public static void print(int[] arr) {
for (int i = 0; i & arr. i++) {
System.out.print(arr[i] + & &);
System.out.println();
public static void main(String[] args) {
int a[] = { 49, 38, 65, 97, 76, 13, 27, 49 };
System.out.println(&排序前
System.out.println(&排序
quickSort(a);
// System.out.println(&任意数组测试:&);
// Random r = new Random();
// int[] testArr = new int[20];
// for (int i = 0; i & 20; i++) {
// testArr[i] = r.nextInt(100);
// System.out.println(&排序前 : &);
// print(testArr);
// System.out.println(&排序后: &);
// print(quickSort(testArr));
输出结果:
49 38 65 97 76 13 27 49
在数组中从0到7基准元素索引:0
快速排序------------&
49 38 65 97 76 13 27 49
27 38 65 97 76 13 49 49
27 38 65 97 76 13 49 49
27 38 49 97 76 13 65 49
27 38 13 97 76 49 65 49
27 38 13 49 76 97 65 49
27 38 13 49 76 97 65 49
在数组中从0到7基准元素索引变换:3
快速排序------------&
13 38 27 49 76 97 65 49
13 27 38 49 76 97 65 49
在数组中从0到2基准元素索引变换:1
快速排序------------&
13 27 38 49 49 97 65 76
13 27 38 49 49 76 65 97
13 27 38 49 49 65 76 97
在数组中从4到7基准元素索引变换:6
13 27 38 49 49 65 76 97
快速排序是一个不稳定的排序方法。
快速排序算法介绍
& & & 快速排序和归并排序都使用分治法来设计算法,区别在于归并排序把数组分为两个基本等长的子数组,分别排好序之后还要进行归并(Merge)操作,而快速排序拆分子数组的时候显得更有艺术,取一个基准元素,拆分之后基准元素左边的元素都比基准元素小,右边的元素都不小于基准元素,这样只需要分别对两个子数组排序即可,不再像归并排序一样需要归并操作。
基本思想:
1)选择一个基准元素,通常选择第一个元素或者最后一个元素,
2)通过一趟排序讲待排序的记录分割成独立的两部分,其中一部分记录的元素值均比基准元素值小。另一部分记录的&元素值比基准值大。
3)此时基准元素在其排好序后的正确位置
4)然后分别对这两部分记录用同样的方法继续进行排序,直到整个序列有序。
快速排序的示例:
(a)一趟排序的过程:
(b)排序的全过程
算法的实现:
import java.util.R
public class QuickSort {
// 快速排序
private static void quickSort(int[] a) {
System.out.println(&在数组中从0到&+(a.length-1)+&基准元素索引:& + 0);
subQuickSort(a, 0, a.length-1);
private static void subQuickSort(int[] a,int start, int end) {
if(a == null || end-start&2){
int keyIndex = quickSortPortion(a, start, end);
System.out.println(&在数组中从&+start+&到&+end+&基准元素索引变换:& + keyIndex);
if(keyIndex == start){
subQuickSort(a, start+1, end);
}else if(keyIndex == end){
subQuickSort(a, start, end-1);
subQuickSort(a, start, keyIndex-1);
subQuickSort(a, keyIndex+1, end);
private static int quickSortPortion(int[] a, int start, int end) {
int minIndex = (end-start) / 2 + // minIndex定义为数组的中间索引
int key = // 将数组的第一个元素的索引定义为基准元素
System.out.println(&快速排序------------&&);
for (int i = i & i++) { // 比较 length-1次
if (key &= minIndex) { // 如果基准元素在前半部分
if (a[key] & a[h]) { // 元素值比基准元素值小
swap(a, key, h); // 交换位置
h = key + 1;
} else { // 如果基准元素在后半部分
if (a[key] & a[h]) { // 元素值比基准元素值大
swap(a, key, h); // 交换位置
h = tmp - 1;
// 交换数组元素
private static void swap(int[] arr, int i, int j) {
if (i == j) {
arr[i] = arr[i] + arr[j];
arr[j] = arr[i] - arr[j];
arr[i] = arr[i] - arr[j];
// 打印数组
public static void print(int[] arr) {
for (int i = 0; i & arr. i++) {
System.out.print(arr[i] + & &);
System.out.println();
public static void main(String[] args) {
int a[] = { 49, 38, 65, 97, 76, 13, 27, 49 };
System.out.println(&排序前
System.out.println(&排序
quickSort(a);
// System.out.println(&任意数组测试:&);
// Random r = new Random();
// int[] testArr = new int[20];
// for (int i = 0; i & 20; i++) {
// testArr[i] = r.nextInt(100);
// System.out.println(&排序前 : &);
// print(testArr);
// System.out.println(&排序后: &);
// print(quickSort(testArr));
输出结果:
49 38 65 97 76 13 27 49
在数组中从0到7基准元素索引:0
快速排序------------&
49 38 65 97 76 13 27 49
27 38 65 97 76 13 49 49
27 38 65 97 76 13 49 49
27 38 49 97 76 13 65 49
27 38 13 97 76 49 65 49
27 38 13 49 76 97 65 49
27 38 13 49 76 97 65 49
在数组中从0到7基准元素索引变换:3
快速排序------------&
13 38 27 49 76 97 65 49
13 27 38 49 76 97 65 49
在数组中从0到2基准元素索引变换:1
快速排序------------&
13 27 38 49 49 97 65 76
13 27 38 49 49 76 65 97
13 27 38 49 49 65 76 97
在数组中从4到7基准元素索引变换:6
13 27 38 49 49 65 76 97
快速排序是一个不稳定的排序方法。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:18673次
积分:1291
积分:1291
排名:千里之外
原创:101篇
转载:70篇
评论:10条
(1)(34)(34)(3)(11)(16)(10)(10)(35)(18)(1)快速排序详解以及java实现
快速排序作为一种高效的排序算法被广泛应用,SUN的JDK中的Arrays.sort 方法用的就是快排。
快排采用了经典的分治思想(divide and conquer):
&Divide:选取一个基元X(一般选取数组第一个元素),通过某种分区操作(partitioning)将数组划分为两个部分:左半部分小于等于X,右半部分大于等于X。
Conquer: 左右两个子数组递归地调用Divide过程。
Combine:快排作为就地排序算法(in place sort),不需要任何合并操作
&可以看出快排的核心部分就是划分过程(partitioning),下面以一个实例来详细解释如何划分数组(图取自于《算法导论》)
&初始化:选取基元P=2,就是数组首元素。i=1,j=i+1=2 (数组下标以1开头)
循环不变量:2~i之间的元素都小于或等于P,i+1~j之间的元素都大于或等于P
循环过程:j从2到n,考察j位置的元素,如果大于等于P,就继续循环。如果小于P,就将j位置的元素(不应该出现在i+1~j这个区间)和i+1位置(交换之后仍在i+1~j区间)的元素交换位置,同时将i+1.这样就维持了循环不变量(见上述循环不变量说明)。直到j=n,完成最后一次循环操作。
要注意的是在完成循环后,还需要将i位置的元素和数组首元素交换以满足我们最先设定的要求(对应图中的第i步)。
细心的读者可能会想到另一种更直白的分区方法,即将基元取出存在另一相同大小数组中,遇到比基元小的元素就存储在数组左半部分,遇到比基元大的元素就存储在数组右半部分。这样的操作复杂度也是线性的,即Theta(n)。但是空间复杂度提高了一倍。这也是快排就地排序的优势所在。
public class QuickSort {
private static void QuickSort(int[] array,int start,int end)
if(start&end)
int key=array[start];//初始化保存基元
int i=start,j;//初始化i,j
for(j=start+1;j&=j++)
if(array[j]&key)//如果此处元素小于基元,则把此元素和i+1处元素交换,并将i加1,如大于或等于基元则继续循环
int temp=array[j];
array[j]=array[i+1];
array[i+1]=
array[start]=array[i];//交换i处元素和基元
QuickSort(array, start, i-1);//递归调用
QuickSort(array, i+1, end);
public static void main(String[] args)
int[] array=new int[]{11,213,134,44,77,78,23,43};
QuickSort(array, 0, array.length-1);
for(int i=0;i&array.i++)
System.out.println((i+1)+&th:&+array[i]);
(window.slotbydup=window.slotbydup || []).push({
id: '2467140',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467141',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467142',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467143',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467148',
container: s,
size: '1000,90',
display: 'inlay-fix'算法练习(1)
用java实现快速排序
1.快速排序的基本思想和算法
& & & &基本思想:通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。
& & & 假设待排序的序列为{L.r[s],L.r[s+1],L.r[s+2],L.r[t],},首先任意选择一个记录(通常选择第一个记录L.r[s])作为枢纽(pivot)。具体实现为如下:
public class QuickSort {
//一次快速排序
private static int QuickSorts(int array[], int low, int high) {
int tmp, tmp2,k=0 ;
int pivotkey = array[low];
int array2[] = new int[100];
while (low & high) {
while (low & high && array[high] &= pivotkey) {
tmp = array[low];
array[low] = array[high];
array[high] =
while (low & high && array[low] &= pivotkey) {
tmp2 = array[high];
array[high] = array[low];
array[low] = tmp2;
array[low] =
System.out.println(&\n参数值为:&+&low=& + low + & high=& + high + & pivotkey=&
+ pivotkey);
System.out.print(&本次排序后的序列为:&);
for(int i=0;i&array.i++){
array2[i]=array[i];
System.out.print(& &+array2[i]);
//递归调用QuickSorts,完成整个快速排序。
private static void Sort(int array[], int low, int high) {
if (low & high) {
dp = QuickSorts(array, low, high);
Sort(array, low, dp - 1);
Sort(array, dp + 1, high);
public static void main(String[] args) {
int[] array = { 10, 3, 2, 15, 20, 1, 0, 9, 17, 25 };
Sort(array, 0, array.length - 1);
}没能实现让输出的时候显示这是第几趟排序。水平比较低。。。。
最后结果为:如图所示
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:57次
排名:千里之外dongdong200514 的BLOG
用户名:dongdong200514
文章数:44
访问量:8362
注册日期:
阅读量:5863
阅读量:12276
阅读量:349809
阅读量:1048760
51CTO推荐博文
\(^)/由于种种原因,很久没有写blog了,总觉得写blog的时间好长额。。。。加上整个假期过来自己都郁闷了一点≡(n)≡。。。。自己趁着假期又新增了兴趣,学了一堆。。。总觉得自己啥米都学了点可是啥米都学不精通,所以还是回归自己最熟悉的语言Java好好学学先,至于其他兴趣再好好学学吧。快速排序的算法复杂度最快和平均的时候都是O(nlog(n)),而且是很多复杂度为O(nlog(n))的排序算法中最快的,所以想先从这个入手说一说,像Java里面的Arrays.sort()里面用的就是快速排序。据书上有一段说法(关于java里面的Arrays.sort()方法的):当n&=40时,它选取的基准元素是(s0,sn/2,sn-1)三者的中间值;n&40时,选取9个间隔相当的元素的中间值,当n&7时,还会切换成插入排序。先列出源代码,再一步一步分析:private static int partition(int[]arr,int low, int high){
int temp = arr[low];
while(low & high){
while(low&high && arr[high]&=temp)
if(low&high)
a[low]=a[high];
while(low&high && arr[low]&=temp)
if(low&high)
a[high]=a[low]
public static void sort(int []arr){
sort(arr, 0 , arr.length);
private static void sort(int[]arr ,int low, int high){
if(high & low)
int m = partition(arr, low, high);
sort(arr, low, m);
sort(arr, m+1, high);
}举例,假如我们现在要排序:arr={46,35,60,94,76,12,28};首先取得基准元素temp=arr[0]=46,此时low=0,low&high,因为arr[high]&temp,退出循环,这时因为arr[low]的值已经另外存储到temp中,所以可以通过arr[low]=arr[high]的方式让较基准元素temp小的值放到temp的左边。然后此时arr[low]=28&=temp,所以low++,移到35,同理low++,到60的时候跳出循环,此时60对应的值比temp大,因为arr[high]的值之前已经存到arr[low]中,所以可以放心地把60这个值放到arr[high]中。因为此时依然符合low&high,所以我们继续走第一层的大循环那么现在arr在准备进入第一层大循环之前的值为:arr={28,35,60,94,76,12,60}我们发现,60出现了两次,不过不用担心,最后a[high]=temp还是会被替换回去的。第二次循环此时low从60开始,high还是从最后一个元素开始。arr的每次结束一次循环的变化应该如下:arr={28,35,12,94,76,94,60}最后赋值有:arr={28,35,12,46,76,94,60}此时可以看出基准元素46的两侧一边比它小,一边比它大,但是还是米有完全排序好的,要怎么才能排序好呢?应该用的就是分治的一种原则啦~~~~看程序中的sort(int []arr, int low,int high)中可以看出来,假设我们第一次sort(arr,low,m),此时相当于sort(arr,0,3),递归调用,high&low,其实觉得直接sort(arr,0,2)比较好,因为觉得没有必要把46重新放入下面的方法中(虽然放了也不会错)。还是改成sort(arr,low, m-1)比较恰当,因为左边的元素总比基准元素m小的,没有必要考虑m。然后此时又会得到一个排序的序列,不停递归调用知道high&low,也就是此时的左边元素已经顺序排序好了~同理也可以进行右边元素的排序了~~~快排的最好和平均的时间复杂度是O(nlogn);分析:算法复杂度其实是跟partition分出的两个子集合是否平衡有关的。在最好的情况下,每次划分都是中值的话那么每次都能划分出(n-1)/2的子集合。在n&1的时候有T(n)=2T(n/2)+O(n),所以复杂度是O(nlogn).而如果已经是排序好的序列,那么会分割出0和n-1元素的子集合,此时在n&1的时候有T(n)=T(n-1)+O(n),所以复杂度是O(n^2)本文出自 “” 博客,请务必保留此出处
了这篇文章
类别:┆阅读(0)┆评论(0)}

我要回帖

更多关于 java编程全能词典 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信