- 前言
- 一、原理
- 以数组{3,4,2,1,5}为例
- 1.确定标准值
- 2.分区
- 3.重复分区
- 左区
- 右区
- 结果
- 二、代码实现
- 1.主方法
- 2.排序
- 结果
- 总结
- 快速排序时间复杂度和稳定性
- 快速排序稳定性
- 快速排序时间复杂度
前言
快速排序的实现,主要是同过确定一个标准值并将小于标准值的数据移到标准值的左边,大于标准值的数据移到标准值的右边,然后对交换完毕后的两个分区重复以上 *** 作,直到分区大小小于2,整个排序过程可以递归进行,以此达到整个数据变成有序序列
一、原理 以数组{3,4,2,1,5}为例 1.确定标准值
确定数组第一个数据为标准值,当作分区的标准,即以此数据为中心将数组分为两个分区
使左下标从当前分区最左边开始向右移,使右下标从当前分区最右边开始向左移
当右下标找到比标准值小的数时停下,以标记此数据
当左下标找到比标准值大的数时停下,以标记此数据
两下标都停下时,交换两数,以实现小于标准值的数据移到标准值的左边,大于标准值的数据移到标准值的右边
重复上述 *** 作,下标相遇时,将标准值与下标相遇所标记的值交换
交换:
此时标准值左边的是小于标准值的,右边的是大于标准值的
对分区后的两组数据重复分区
左区确定标准值:
相遇:
此时右下标所指的数据小于标准值2,所以不需要移动;左下标移动一位后与右下标相遇
交换:
确定标准值:
相遇:
右下标移动一位,即与左下标相遇
交换:
相遇位置与标准值初始位置相同
红:一次标准值
绿:二次左区标准值
蓝:二次右区标准值
代码如下:
public class KuaiSu {
public static void main(String[] args) {
int n[] = {3,4,2,1,5};//初始数组
sort(n,0,n.length - 1);//调用排序方法
for (int i: n) {
System.out.print(i + " ");//遍历排序后的数组
}
}
}
2.排序
代码如下:
public static void sort(int n[],int l,int r) {
if (l < r) {//判断本组数组长度是否小于2
int p = n[l];//记录标准值
int i = l;//记录左下标
int j = r;//记录右下标
while (i < j) {//当左下标小于右下标
while (n[j] >= p && i < j) {//当右下标指定的值大于标准值,且左下标小于右下标
j--;//右下标左移一位
}
while (n[i] <= p && i < j) {//当左下标指定的值小于标准值,且左下标小于右下标
i++;//左下标右移一位
}
//以上两条件均不满足时,交换当前左右下标指定的值
int temp = n[i];
n[i] = n[j];
n[j] = temp;
}
//将标准值与左右下标最后相遇的值交换
n[l] = n[i];
n[i] = p;
//递归调用排序方法,实现左右两组分别排序
sort(n,l,i - 1);
sort(n,i + 1,r);
}
}
结果
总结 快速排序时间复杂度和稳定性 快速排序稳定性
快速排序是不稳定的算法,它不满足稳定算法的定义。
算法稳定性 -- 假设在数列中存在a[i]=a[j],若在排序之前,a[i]在a[j]前面;并且排序之后,a[i]仍然在a[j]前面。则这个排序算法是稳定的!
快速排序时间复杂度
快速排序的时间复杂度在最坏情况下是O(N2),平均的时间复杂度是O(N*lgN)。
这句话很好理解:
假设被排序的数列中有N个数。遍历一次的时间复杂度是O(N),需要遍历至少lg(N+1)次,最多N次。
- 为什么最少是lg(N+1)次?
快速排序是采用的分治法进行遍历的,我们将它看作一棵二叉树,它需要遍历的次数就是二叉树的深度,而根据完全二叉树的定义,它的深度至少是lg(N+1)。因此,快速排序的遍历次数最少是lg(N+1)次。 - 为什么最多是N次?
还是将快速排序看作一棵二叉树,它的深度最大是N。因此,快读排序的遍历次数最多是N次
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)