您的位置:首页 > 编程语言 > Java开发

"快速排序"算法-之通俗易懂全面解析

2016-06-07 21:59 465 查看

1.概念和特点介绍

要说到几个java的经典算法,快速排序不得不提,这个高效和快速的算法一直是每个java学习者必会的算法,该算法结合递归进行,下面我就详细的通过代码和图片的方式给大家讲解快速排序,希望能帮组想要学习的朋友.
开始写代码之前我可以告诉朋友们,快速算法到底有多快,举个例子(大家可用试试),随机产生50万个1-100的随机数值,分别放入数组,如果用插入排序,所花的时间大概是90多秒,快速排序呢?两秒不到!一般是半秒到一秒多之间,所以这就是为什么把它成为快速算法的原因.
我们在开发过程中用到的数组工具Arrays.sort(int[] arr)就是采用的快速算法,那么现在我们就通过代码学习来详细的认识该算法吧.


2.图解分析过程

通过一个图给大家分析一下



如果还有不明白过程的朋友,再看看下面一张图就能理解了



3.详细代码

下面通过代码的形式给大家写出进行快速排序的详细过程

/**
* 使用工具Arrays.sort(int[] arr)里边就是快速排序;
*      快速排序(重点是找mid值,找到一个mid就相当于找到固定了一个数的位置了)
*      1.定义一个基数,最右边的
*      2.从左边找第一个比基数大的
*      3.从右边找第一个比基数小的
*      4.找到就换角标对应的值
*      5.继续找 如果找到了,并交叉了left和right就让left和temp互换,就找到一个mid了 如果到不到就判断left和right的关系
*      6.找到mid就继续递归
*
*/
public class Demo06 {
public static void main(String[] args) {
//定义一个数组
int[] ints = { 5, 3, 2, 1, 4 };
//排序前打印一下
printUtils.printArray(ints);
quicklySort(ints);
//排序后再打印一下
printUtils.printArray(ints);

}
//给方法传入数组
private static void quicklySort(int[] ints) {
//确定数组的首位和末位置
sort(ints, 0, ints.length - 1);
}

// 为了获取mid
private static void sort(int[] ints, int left, int end) {
//方法如果发现left>end了说明越界了,结束即可
if (left > end) {
return;
}
//定义一个方法专门找中间值
int mid = findMiddle(ints, left, end);
//找到了中间值,递归左一半
sort(ints, left, mid - 1);
//递归右一半
sort(ints, mid + 1, end);
}

private static int findMiddle(int[] ints, int left, int end) {
int mid = -1;
//右边值等于倒数第二个
int right = end - 1;
//基数等于最后一个
int temp = ints[end];
/*--------------1.死循环找mid--------------*/
//循环获取所有的固定mid
while (true) {
/*--------------2.循环防越界找大小--------------*/
// 1.从左边找比temp大的
while (left < end && !(ints[left] > temp)) {//left<end防越界
left++;
}
// 2.从右边找比temp小的
while (right > left && !(ints[right] < temp)) {//right>=left防越界
right--;
}
/*--------------判断是否到达左角标是否到达右边--------------*/
if (left == end) {// 超过了end,说明没有比end更大的了
mid = end;
return mid;
}

if (left < right) {// 找到了但未交叉,换角标值
int tem = ints[left];
ints[left] = ints[right];
ints[right] = tem;
} else {// 交叉
int tem = ints[end];
ints[end] = ints[left];// left角标值 和 temp换
ints[left] = tem;
mid = left;// 得到mid
return mid;
}
}
}
}


写法二:就是不封装找mid的方法,直接写在一起

public class Example2 {
public static void main(String[] args) {
int[] ints = initUtils.initData(10);

printUtils.printArray(ints);
quicklySort(ints);
printUtils.printArray(ints);
}

private static void quicklySort(int[] ints) {
sort(ints, 0, ints.length - 1);
}

private static void sort(int[] a, int left, int end) {
if (left > end)
return;// 如果left>end,停止

int mid = -1;
int right = end - 1;
int start = left;
int temp = a[end];
//***注意如果不想通过放在finMid()方法找mid,而是直接这样写,那么就用一个star代替left,因为递归sort(里的left)要和第一次方法里的left相同,所以用start代替.
while (true) {
while (start < end && !(a[start] > temp))
start++;// 防越界和循环找到
while (right > start && !(a[right] < temp))
right--;

if (start == end) {
mid = end;
break;
}
if (start < right) {//换left right对应值
int tem = a[start];
a[start] = a[right];
a[right] = tem;

} else {//交叉left temp
int tem = a[start];
a[start] = a[end];
a[end] = tem;
mid = start;
break;
}
}
sort(a, left, mid - 1);
sort(a, mid + 1, end);
}
}


4.总结

快速排序,重点就是要记住3步:
1.确定基数(最右边),从左找第一个比基数大的,从右边找第一个比基数小的.
2.替换left和right对应的值,继续找,交叉后替换left的和基数对应的值,此时即可确定mid
3.有了mid就把数组分成了两半,此时采用递归:左边left到mid-1;右边mid+1到end,即可轻松完成快速排序.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息