快速排序是基于冒泡排序,是改进性冒泡排序,效率更高;
思路
1.设定一个分界值,将数据分成两部分;
2.将小于分界值放在左边,将大于分界值放在右边;左边数据小于等于分界值, 右边数据大于等于分界值。
3.对分界值左右边分别排序;
4.在数据左右边找出一个分界值重复上述步骤;Demo 完整源码地址
/**
* @Title: 排序基本算法
* @Package ${package_name}
* @Description: 排序基本算法
* Created by eason_hoo on 16/8/7.
*/
public abstract class BaseSorter {
//构造sort函数
public abstract void sort(int[] array);
}
/**
* @Title: 快速排序
* @Package ${package_name}
* @Description: 快速排序 是冒泡排序的改进型,效率更高
* 冒泡排序 数据之间的比较次数太多,快速排序是
* 找到一个中间值把数据分成两等份把的比其小的放
* 左手边 比其大放右手边
* Created by eason_hoo on 16/9/4.
*/
public class QuickSorter extends BaseSorter {
@Override
public void sort(int[] array) {
this.quickSort(array,0, array.length - 1);
}
/**
* 交换两个数据值
* @param arr
* @param i
* @param j
*/
private void swap(int[] arr, int i, int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
/**
* 查询基准值
* @param arr 原始值
* @param left
* @param right
*/
private int partition(int[] arr, int left, int right){
/**默认最左边为基准值**/
int pointV = arr[left];
while (left < right){
/**从右边开始和基准值比较, 如arr[n-i] >= 基准值pointV 索引值right-- 否则交换和基准值交换**/
while (left < right && arr[right] >= pointV)
right--;
this.swap(arr,left,right);
/**从d左边开始和基准值比较, 如arr[n-i] <= 基准值pointV 索引值left++ 否则交换和基准值交换**/
while (left < right && arr[left] <= pointV)
left++;
this.swap(arr,left,right);
}
return left;
}
/**
* 递归快速排序
* @param arr
* @param left 左边最小序号
* @param right 右边最大序号
*/
private void quickSort(int[] arr, int left,int right){
if (left < right){
/**确定基准值下角标值pointV**/
int pointV = this.partition(arr,left,right);
/**递归左遍历 left 至 pointV-1**/
this.quickSort(arr,left,pointV - 1);
/**递归右遍历 pointV+1 至 right**/
this.quickSort(arr,pointV + 1,right);
}
}
}
- 算法分析
1.时间复杂度
最后的情况在基准值左右两边无序子区间长度是一样的,总的关键数比较次数为: O(nlgn)
最后的情况划分出n-1区 每i次需要比较n-i-1 次 总的比较次数为n(n-1)/2 =O(n^2)
2.空间复杂度
快速排序内部需要一个栈实现递归,划分均匀,则递归树的高度为O(lgn) 递归后需要栈的空间为O(lgn) 所以需要的空间为O(lgn)
3.算法稳定性
排序不稳定