数据结构与算法——快速排序算法
算法描述
快速排序是基于分治的思想,是冒泡排序的改进型。首先在数组中选择一个基准点(该基准点的选取可能会影响快速排序算法的效率),然后分别从数组的两端扫描数组。设两个指示标志(low指向起始位置,high指向末尾位置),首先从后半部分开始,如果发现有元素比该基准点的值小,就交换low和high位置的值,然后从前半部分开始扫描,发现有元素大于基准点的值,就交换low和high位置的值,如此往复循环,直到low>=high,然后把基准点的值放到high这个位置,一次排序就完成了。以后采用递归的方式分别对前半部分和后半部分排序,以达到整个序列有序的目的。
代码实现:
1 public class QuickSort { 2 3 public void quickSort(int[] arr,int low,int high) { 4 int pivot; 5 if(low<high) { 6 pivot=partition(arr,low,high); 7 quickSort(arr,low,pivot-1); 8 quickSort(arr,pivot+1,high); 9 } 10 } 11 12 public int partition(int[] arr,int low,int high) { 13 int pivotKey; 14 pivotKey=arr[low]; 15 while(low<high) { 16 while(low<high && arr[high]>=pivotKey) { 17 high--; 18 } 19 swap(arr,low,high); 20 while(low<high && arr[low]<=pivotKey) { 21 low++; 22 } 23 swap(arr,low,high); 24 } 25 return low; 26 } 27 28 public void swap(int[] arr,int i,int j) { 29 int temp=arr[i]; 30 arr[i]=arr[j]; 31 arr[j]=temp; 32 } 33 }
优化一:优化选取的基准点
1 public class QuickSort { 2 /* 3 * 三数取中(选取基准点) 4 * 5 */ 6 public void quickSort(int[] arr,int low,int high) { 7 int pivot; 8 if(low<high) { 9 pivot=partition(arr,low,high); 10 quickSort(arr,low,pivot-1); 11 quickSort(arr,pivot+1,high); 12 } 13 } 14 public int partition(int[] arr,int low,int high) { 15 int pivotKey; 16 int mid=(low+high)/2; 17 if(arr[low]>arr[high]) { 18 swap(arr,low,high); 19 } 20 if(arr[mid]>arr[high]) { 21 swap(arr,mid,high); 22 } 23 if(arr[mid]>arr[low]) { 24 swap(arr,low,mid); 25 } 26 pivotKey=arr[low]; 27 while(low<high) { 28 while(low<high && arr[high]>=pivotKey) { 29 high--; 30 } 31 swap(arr,low,high); 32 while(low<high && arr[low]<=pivotKey) { 33 low++; 34 } 35 swap(arr,low,high); 36 } 37 return low; 38 39 } 40 public void swap(int[] arr,int i,int j) { 41 int temp=arr[i]; 42 arr[i]=arr[j]; 43 arr[j]=temp; 44 } 45 }
优化二:优化不必要的交换
1 public class QuickSort { 2 public void quickSort(int[] arr,int low,int high) { 3 int pivot; 4 if(low<high) { 5 pivot=partition(arr,low,high); 6 quickSort(arr,low,pivot-1); 7 quickSort(arr,pivot+1,high); 8 } 9 } 10 public int partition(int[] arr,int low,int high) { 11 int pivotKey; 12 int mid=(low+high)/2; 13 if(arr[low]>arr[high]) { 14 swap(arr,low,high); 15 } 16 if(arr[mid]>arr[high]) { 17 swap(arr,mid,high); 18 } 19 if(arr[mid]>arr[low]) { 20 swap(arr,low,mid); 21 } 22 pivotKey=arr[low]; 23 while(low<high) { 24 while(low<high && arr[high]>=pivotKey) { 25 high--; 26 } 27 arr[low]=arr[high];//采用替换而不是交换的方式进行操作 28 while(low<high && arr[low]<=pivotKey) { 29 low++; 30 } 31 arr[high]=arr[low];//采用替换而不是交换的方式进行操作 32 } 33 arr[low]=pivotKey; 34 return low; 35 } 36 public void swap(int[] arr,int i,int j) { 37 int temp=arr[i]; 38 arr[i]=arr[j]; 39 arr[j]=temp; 40 } 41 }
快速排序算法的复杂度分析
最优情况:最优情况下是指每次区间划分的结果都是基准关键字的左右两边长度相等或者相差为1,即选取的基准关键字为待排序的记录的中间值。此时的时间复杂度为O(nlogn)。
最坏情况:最坏情况下,待排序的序列为正序或者逆序,每次划分只得到一个比上一次划分少一个记录的子序列,注意另一个为空。此时的时间复杂度为O(n2)。
空间复杂度:就空间复杂度来说,主要是递归造成的栈空间的使用,最好情况,递归树的深度为log2n,其空间复杂度为O(logn),最坏情况,需要进行n-1递归调用,其空间复杂度为O(n),平均情况,空间复杂度为O(logn)。
算法的稳定性:快速排序是一种不稳定的排序方法。
posted on 2018-04-01 19:05 Joyce&wang 阅读(1091) 评论(0) 收藏 举报