快速排序:
public class QuickSort {
public static void main(String[] args) {
int[] a=new int[]{49,38,65,97,76,13,27,49};
int n=a.length;
Quicksort0(a,0,n-1);
for (int c=0;c<n;c++){
System.out.print(a[c]+" ");
}
System.out.println();
}
static void Quicksort0(int[] a,int low,int high){
if (low<high){//递归跳出条件
//Partition()就是划分操作,将表a[low.....high]划分为满足上述条件的两个子表
int pivotpos=Partition(a,low,high); //划分
Quicksort0(a,low,pivotpos-1); //依次对两个子表进行递归排序,这是比枢轴元素小的一边
Quicksort0(a,pivotpos+1,high); //这是比枢轴元素大的一边
}
}
//一趟划分
static int Partition(int[] a, int low, int high) {
int pivot=a[low]; //枢轴
while(low<high){
while (low<high&&a[high]>=pivot) --high;
a[low]=a[high]; //将比枢轴小的元素移动到左端
while (low<high&&a[low]<=pivot) ++low;
a[high]=a[low]; //将比枢轴大的元素移动到右端
}
a[low]=pivot;
return low;
}
}
时间复杂度:O(n^2)
快速排序是所有内部排序算法中平均性能最优的排序算法。
先熟悉排序流程、逻辑和概念
(1)首先设定一个分界值,通过该分界值将数组分成左右两部分。
(2)将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于分界值,而右边部分中各元素都大于或等于分界值。
(3)然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。
(4)重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好
简单来说:
最开始学习编程,遇到排序问题,一般都是用冒泡法,因为冒泡法好理解,代码量少。但是这种算法时间复杂度高,当需要排序的元素较多时,程序运行时间很长,因此产生了快速排序算法。该算法的实现可分为以下几步:
1. 在数组中选一个基准数(通常为数组第一个);
2. 将数组中小于基准数的数据移到基准数左边,大于基准数的移到右边;
3. 对于基准数左、右两边的数组,不断重复以上两个过程,直到每个子集只有一个元素,即为全部有序。
右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。
可能描述得有些抽象,接下来用图一步一步的示意:
将数组第一个数23赋给temp变量,指针 i 指向数组第一个元素,指针 j 指向数组最后一个元素
从 j 开始遍历(从右往左),遇到13时,因为13<=temp,因此将arr[j]填入arr[i]中,即此时指针 i 指向的数为13;
再从 i 遍历(从左往右),遇到45时,因为45>temp,因此将arr[i]填入arr[j]中,此时指针 j 指向的数为45;
继续从 j 遍历,遇到11时,因为11<=temp,因此将arr[j]填入arr[i]中,即此时指针 i 指向的数为11;
从 i 遍历,遇到89时,因为89>temp,因此将arr[i]填入arr[j]中,此时指针 j 指向的数为89;
从 j 遍历,遇到17时,因为17<=temp,因此将arr[j]填入arr[i]中,即此时指针 i 指向的数为17;
从 i 遍历,遇到72时,因为72>temp,因此将arr[i]填入arr[j]中,此时指针 j 指向的数为72;
从 j 遍历,遇到3时,因为3<=temp,因此将arr[j]填入arr[i]中,即此时指针 i 指向的数为3;
从 i 遍历,遇到26时,因为26>temp,因此将arr[i]填入arr[j]中,此时指针 j 指向的数为26;
从 j 遍历,和 i 重合;
将 temp(基准数23)填入arr[i]中。