算法步骤:
1.在待排序的元素任取一个元素作为基准(通常选第一个元素,但最佳的选择方法是在待排序数组中随机选取一个作为基准),成为基准元素。
2.将待排序的元素进行分区,比基准元素大的元素放在它的右边,比其小的放在它的左边。
3.对左右两个分区重复以上步骤直到所有元素都是有序的。
时间复杂度:快速排序在最好情况下时间复杂度为O(nlogn),最坏情况下时间复杂度为O(n2);
稳定性分析:
要分析稳定性,那么就需要关注快速排序中对基准元素相等的数的处理方式。在快速排序中,左右哨兵搜索时,对于相等数并不敏感,两边遇到相等数后都会选择无视,然后继续搜索下一个数,这样问题就出现了:
以基准数为第一个数为例,那么相等的数是位于基准数右边的,与原先的基准数、相等数二者之间次序相同,是稳定的;另一方面,如果左边哨兵发现了相等数,也不对其进行操作,那么相遇点肯定就在相等数的右边了,最终基准数被交换到相等数的右边,此时相等数与基准数之间的次序改变了,是不稳定的。
综上所述,快速排序是一种不稳定的排序算法。
代码实现:
第一种方法:
1 public class QuickSort {
2 public static void quickSort(int arr[],int _left,int _right){
3 int left = _left;
4 int right = _right;
5 int temp = 0;
6 if(left <= right){ //待排序的元素至少有两个的情况
7 temp = arr[left]; //待排序的第一个元素作为基准元素
8 while(left != right){ //从左右两边交替扫描,直到left = right
9 while(right > left && arr[right] >= temp)
10 right --; //从右往左扫描,找到第一个比基准元素小的元素
11 arr[left] = arr[right]; //找到这种元素arr[right]后与arr[left]交换
12 while(left < right && arr[left] <= temp)
13 left ++; //从左往右扫描,找到第一个比基准元素大的元素
14 arr[right] = arr[left]; //找到这种元素arr[left]后与arr[right]交换
15 }
16 arr[right] = temp; //基准元素归位
17 quickSort(arr,_left,left-1); //对基准元素左边的元素进行递归排序
18 quickSort(arr, right+1,_right); //对基准元素右边的进行递归排序
19 }
20 }
21 public static void main(String[] args) {
22 int array[] = {10,5,3,1,7,2,8};
23 System.out.println("排序之前:");
24 for(int element : array){
25 System.out.print(element+" ");
26 }
27 quickSort(array,0,array.length-1);
28 System.out.println("
排序之后:");
29 for(int element : array){
30 System.out.print(element+" ");
31 }
32 }
33 }
第二种方法:
1 public void sort(int[] a,int low,int high){
2 int start = low;
3 int end = high;
4 int key = a[low];
5 while(end>start){
6 //从后往前比较
7 while(end>start&&a[end]>=key)
8 //如果没有比关键值小的,比较下一个,直到有比关键值小的交换位置,然后又从前往后比较
9 end--;
10 if(a[end]<=key){
11 int temp = a[end];
12 a[end] = a[start];
13 a[start] = temp;
14 }
15 //从前往后比较
16 while(end>start&&a[start]<=key)
17 //如果没有比关键值大的,比较下一个,直到有比关键值大的交换位置
18 start++;
19 if(a[start]>=key){
20 int temp = a[start];
21 a[start] = a[end];
22 a[end] = temp;
23 }
24 //此时第一次循环比较结束,关键值的位置已经确定了。左边的值都比关键值小,右边的值都比关键值大,但是两边的顺序还有可能是不一样的,进行下面的递归调用
25 }
26 //递归
27 if(start>low) sort(a,low,start-1);//左边序列。第一个索引位置到关键值索引-1
28 if(end<high) sort(a,end+1,high);//右边序 列。从关键值索引+1 到最后一个
29 }
30 }