什么是快速排序算法?
冒泡排序大家应该都是知道的把。冒泡排序每次扫描时只对相邻连个元素进行比较,因此做一次交换也只能消除一个逆序。如果通过交换两个不相邻的元素就可以一次小出多个逆序,那么必将加快排序的速度!
C.R.Hoare于1962年提出了一种划分交换排序,由于他几乎是最快的排序算法,所以被称为快速排序算法。它采用了一种分治的策略,分治的基本思想就是将原问题分解成若干个规模更小但结构相同的子问题,递归的解决这些子问题,然后将这些子问题的解组合为原为题的解。
一个记录序列的关键字分别为3,5,8,1,2,9,4,7,6我们就用这个数组来练习快速排序算法的实现过程。
我想信大家在看了上面的动画后都大概理解了快速排序算法的思想。
我来给大家说说一趟快速排序是如何实现的。
1.我们需要选定一个枢轴,我们默认选则第一个元素,一般后我们会数组的第一个原素作为监视哨来使用,所以实际存储的元素下标是从1开始的,我们就用这个0号位置来存储我们的枢轴
2.我们需要设置两个指针L和R分别指向arr[1]和arr[n],这是我们将arr[1]存入监视哨。
3.比较枢轴的值于R指针指向的数组下标所对应的值得大小,如果比枢轴值大则后退R指针,继续比较,如果比枢轴值小,则将L所指向的值设置为当前R所指向的值,然后前移L指针,用当前的L所指向的值与枢轴值进行比较,如果小于枢轴值则L前移,否则使当前L所指向的值等于当前R所指向的值,R前移重复上述步骤。
4.当R和L同时指向某一数组下标,这时,我们将枢轴值填入该下标,一趟快速排序结束!
我们下面用代码实现一下快速排序算法:
一趟快速排序:
//待排序数组
private int[] arr= {-1,3,5,8,1,2,1,9,4,7,6};
//定义一轮快排方法
public int Sorting(int low,int high) {
//标记位置为待排序数组段的low处也就时枢轴值
arr[0]=arr[low];
while(low<high) {
/**
* 如果当前数字已经有序的位于我们的枢轴两端,我们就需要移动它的指针,是high或是low
*/
while(low<high && arr[high]>=arr[0]) {
high--;
}
/**
* 如果当前数字不满足我们的需求,我们就需要将当前数字移动到它应在的一侧
*/
arr[low]=arr[high];
while(low<high && arr[low]<=arr[0]) {
low++;
}
arr[high]=arr[low];
}
arr[low]=arr[0];
return low;
}
快速排序(递归实现):
public void qsort(int low,int high) {
/**
* 调用这个递归还是是千万记住需要判断low和high的大小,不然会陷入递归的一支中无限延伸直至达到编译器规定的最大递归深度然后报错,多惨呀!
*/
if(low<high) {
int pos=Sorting(low,high);
qsort(low,pos-1);
qsort(pos+1,high);
}
}
测试:
@Test
public void fun1() {
qsort(1,arr.length-1);
System.out.println(Arrays.toString(arr));
}
运行结果:
[4, 1, 2, 3, 4, 5, 6, 7, 8, 9]
数组的零号位置为监视哨哦!
所以可以看出排序还是相当成功的!