Java快速排序算法的实现

高快省的排序算法

有没有既不浪费空间又可以快一点的排序算法呢?那就是“快速排序”啦!光听这个名字是不是就觉得很高端呢。

假设我们现在对“6  1  2  7  9  3  4  5 10  8”这个10个数进行排序。首先在这个序列中随便找一个数作为基准数(不要被这个名词吓到了,就是一个用来参照的数,待会你就知道它用来做啥的了)。为了方便,就让第一个数6作为基准数吧。接下来,需要将这个序列中所有比基准数大的数放在6的右边,比基准数小的数放在6的左边,类似下面这种排列:

3  1  2  5  4  6  9  7  10  8

在初始状态下,数字6在序列的第1位。我们的目标是将6挪到序列中间的某个位置,假设这个位置是k。现在就需要寻找这个k,并且以第k位为分界点,左边的数都小于等于6,右边的数都大于等于6。想一想,你有办法可以做到这点吗?

排序算法显神威

方法其实很简单:分别从初始序列“6  1  2  7  9  3  4  5  10  8”两端开始“探测”。先从找一个小于6的数,再从找一个大于6的数,然后交换他们。这里可以用两个变量i和j,分别指向序列最左边和最右边。我们为这两个变量起个好听的名字“哨兵i”和“哨兵j”。刚开始的时候让哨兵i指向序列的最左边(即i=1),指向数字6。让哨兵j指向序列的最右边(即=10),指向数字。

094811yilrz1tkzkvlrriz.png

首先哨兵j开始出动。因为此处设置的基准数是最左边的数,所以需要让哨兵j先出动,这一点非常重要(请自己想一想为什么)。哨兵j一步一步地向左挪动(即j--),直到找到一个小于6的数停下来。接下来哨兵i再一步一步向右挪动(即i++),直到找到一个数大于6的数停下来。最后哨兵j停在了数字5面前,哨兵i停在了数字7面前。

095430axy0qkhxxkktkktk.png

095437kdandfxhbtokk2qh.png

现在交换哨兵i和哨兵j所指向的元素的值。交换之后的序列如下:

6  1  2  5  9 3  4  7  10  8

095448k1kevwlz41373e7k.png

095458ejza15wscjv7iw5c.png

到此,第一次交换结束。接下来开始哨兵j继续向左挪动(再友情提醒,每次必须是哨兵j先出发)。他发现了4(比基准数6要小,满足要求)之后停了下来。哨兵i也继续向右挪动的,他发现了9(比基准数6要大,满足要求)之后停了下来。此时再次进行交换,交换之后的序列如下:

6  1  2  5  4  3  9  7  10  8

第二次交换结束,“探测”继续。哨兵j继续向左挪动,他发现了3(比基准数6要小,满足要求)之后又停了下来。哨兵i继续向右移动,糟啦!此时哨兵i和哨兵j相遇了,哨兵i和哨兵j都走到3面前。说明此时“探测”结束。我们将基准数6和3进行交换。交换之后的序列如下:

3  1  2  5  4  6  9  7  10  8

095506uz7e1uuukcblhkxv.png

095514cag5fumuqqg5jnsw.png

095530e0jf6p0y6aaaw2ir.png

到此第一轮“探测”真正结束。此时以基准数6为分界点,6左边的数都小于等于6,6右边的数都大于等于6。回顾一下刚才的过程,其实哨兵j的使命就是要找小于基准数的数,而哨兵i的使命就是要找大于基准数的数,直到i和j碰头为止。

OK,解释完毕。现在基准数6已经归位,它正好处在序列的第6位。此时我们已经将原来的序列,以6为分界点拆分成了两个序列,左边的序列是“3  1  2  5  4”,右边的序列是“9  7  10  8”。接下来还需要分别处理这两个序列。因为6左边和右边的序列目前都还是很混乱的。不过不要紧,我们已经掌握了方法,接下来只要模拟刚才的方法分别处理6左边和右边的序列即可。

java代码实现:

public class QuicksortDemo {
public static void main(String[] args) {
// 快速排序算法
int[] arrays = { 6, -2, 12, 1, -1, 2, 11, 7, 9, 3, 4, 11, 5, -5, -4,
13, 10, 8, 0, -6, 19 };
arrays = quicksort(0, arrays.length, arrays);
for (int i : arrays) {
System.out.print(i + " ");
}
}
public static int[] quicksort(int i, int j, int[] arrays) {
if (j - i == 1) {
return arrays;
}
if (i >= arrays.length) {
return arrays;
}
int base = arrays[i];// 基准值
int k = i;
int length = j;
for (--j; j > i; j--) {
if (arrays[j] < base) {// 出现基准数右边的数比基准数小
for (; k < length; k++) {
if (k == j) {
int temp = arrays[k];
arrays[k] = arrays[i];
arrays[i] = temp;

 // 对所有比基准数小的数快速排序

quicksort(k + 1, length, arrays);

// 对所有比基准数大的数快速排序
quicksort(i, k, arrays); 

return arrays;

} else if (arrays[k] > base) {
int temp = arrays[k];
arrays[k] = arrays[j];
arrays[j] = temp;
break;
}
}
}
}

// 当基准数右边的数都比基准数大,对所有比基准数大的数快速排序
return quicksort(i + 1, length, arrays);

}
}

运行结果如下:

-6 -5 -4 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 11 12 13 19 

Java快速排序实现算法改进

public class QuickSort {
public static void main(String[] args) {
// 快速排序
int[] arrays = {-1,9,-1,3,0};
arrays = quicksort(0, arrays.length-1, arrays);
for (int i : arrays) {
System.out.print(i + " ");
}
}
public static int[] quicksort(int i, int j, int[] arrays) {
if (i >= arrays.length) {
return arrays;
}
int base = arrays[i];// 基准值
for (; j > i; j--) {
if (arrays[j] < base) {// 出现基准数右边的数比基准数小
for (int k = i;; k++) {
if (k == j) {
int temp = arrays[j];
arrays[j] = base;
arrays[i] = temp;
// 对所有比基准数小的数快速排序
quicksort(j + 1, arrays.length-1, arrays);
// 对所有比基准数大的数快速排序
quicksort(i, j, arrays);
return arrays;


} else if (arrays[k] > base) {//出现基准数左边的数比基准数大
int temp = arrays[k];
arrays[k] = arrays[j];
arrays[j] = temp;
break;
}
}

}
// 当基准数右边的数都比基准数大,对所有比基准数大的数快速排序
return quicksort(i + 1, arrays.length-1, arrays);
}
}


猜你喜欢

转载自blog.csdn.net/wsxujiacheng/article/details/52993514