想要变优秀,顺其自然是不可能的
你需要做很多,花很多时间,忍耐并且坚持。
快速排序,简称快排,也是初级面试里面被问到最多的排序算法,在普通使用情况下(数据基本无序,数据量n巨大),相对于直接插入排序,简单选择排序,冒泡法排序,快速排序的效率都会更优。这是由冒泡排序改进的算法,也是一种基于交换排序的算法,但是不同于冒泡排序,冒泡排序每次只比较交换相邻的两个元素,每次只消除两个元素之间的逆序,但是快速排序通过两个相邻或者不相邻的元素的交换,能消除多个逆序,极大地加快排序的速度。
下面是每次进行冒泡排序时的模式,这个过程中,因为每次只会交换相邻两个元素的位置,所以只会修改这两个元素的顺序
相对于快速排序,一次可能消除多个逆序的情况,随机选择一个记录anchor(一般选择第一个元素),通过一趟排序把比anchor大的值放到右子表,比anchor小的值放到左子表,再对左右子表使用同样的方式进行划分,直到每个子表都只有一个元素。
对于每一趟循环,首先设定low和high指向左右两个边界:
1、比较右边界high和anchor的大小,如果high大于anchor的值,那么high--,如果是小于anchor的值,那么交换anchor和high的位置,如果找到了比anchor小的值,那么到达第2步
2、比较左边界low和anchor的大小,如果low小于anchor的值,那么low++,如果是大于anchor的值,那么交换anchor和low的位置,返回第1步
3、重复第1步和第2步,直到low == high为止。
刚好碰巧第一个元素就是整个数组最小的,这里我们也看到了,要是元素最小的话,那么效率就跟普通的冒泡排序差不多一样了。如果我们的序列一开始就是基本有序的,快速排序算法(一次交换消除多个元素的逆序)的优势就不明显了。
private static int Partition(int[] num,int low,int high){
int anchor = num[low]; //用第一个元素作为anchor
//当low == high的时候退出循环
while(low <high){
// 如果anchor的值小于high,high左移
while(low <high && anchor < num[high]) high--;
num[low] = num[high];
// 如果anchor的值大于high,low右移
while(low < high && anchor >= num[low]) low++;
//当前的low值大于anchor,让low位置的值移动anchor的位置
num[high] = num[low];
}
//跳出循环时,anchor不再移动
num[high] = anchor;
return high;
}
private static void QuickSort(int[] num,int low,int high){
if (low < high) {
//第一趟排序后anchor的位置
int index = Partition(num, low, high);
QuickSort(num, low, index - 1);
QuickSort(num, index+1, high);
}
}
算法特点
最好的情况是待排序的集合无序,最坏情况带排序集合基本有序,平均情况下的时间复杂度为O(nlogn),空间复杂度最好情况下为O(logn),最坏情况为O(n),适用于初始记录无序,n较大的情况。