首页 > 代码库 > 排序算法之快速排序
排序算法之快速排序
快速排序是一个速度非常快的交换排序算法,思路比较简单:从一个待排的数据序列中任取一个数据作为分界值,所有比这个值小的数据放到这个数的左边,比这个值大的数据放到右边,这样经过一次下来,这个序列分成了左右两个序列,左边的数据都比分界值小,右边的数据都比分界值大,然后再对左右两个子序列进行递归。所以,快速排序的关键在于第一趟要做的事情。实现思路如下:
(1)、选出一个分界值。
(2)、从左往右选出一个比分界值大的数,记录下标 i。
(3)、从右往左选出一个比分界值小的数,记录下标 j。
(4)、如果 i < j 交换两个下标处的元素。
(5)、最后将分界值与 j 下标的元素交换,这样经过第一趟,就把这组数分成了左右两个序列+分界值,左边的序列比分界值小,右边的比分界值大。
比如这组数:15、9、23、6、4、37、7、24
首先15作为分界值,i 从左往右遍历,找到23比15大,记录这个下标 i=2; j 从右往左遍历,找到7小于15,记录这个下标 j=6; 满足条件 i< j , 所以交换这两个数。这组元素变成了:
15、9、7、6、4、37、23、24 然后 i 继续往右,j 继续往左,又找到了4 和 37 此时 i = 5 , j = 4 . 不满足 i < j ,所以不交换,并且跳出第一趟,并且4和15交换。这组数变成了:4、9、7、6、15、37、23、24,这就是第一趟的结果,然后递归左右两个序列。用Java具体实现如下:
package test.java.sort.demo; import test.java.sort.Util.DataWrap; /** * 2017-5-16 Java实现快速排序 * @author tom */ public class FastSortDemo { /** * 交换数组中下标为i和下标为j的两个数 * @param data * @param i * @param j */ private static void swap(DataWrap[] data, int i, int j) { DataWrap temp = data[i]; data[i] = data[j]; data[j] = temp; } public static void fastSort(DataWrap[] data, int start, int end) { // 需要排序 if (start < end) { // 以第一个元素作为界点 DataWrap base = data[start]; int i = start; int j = end + 1; while (true) { // 如果从左到右找到了比分界点大的值,就跳出当前循环,此时i的值记录了这个数的索引 while (i < end && data[++i].compareTo(base) <= 0); // 如果从右往左找到了比分界值小的值,跳出当前循环,此时j的值记录了该数的索引 while (j > start && data[--j].compareTo(base) >= 0); //i<j时才需要交换,如果i>=j还没有找到左边比分界值大,右边比分界值小的数,说明已经达到了第一趟的要求 if (i < j) { swap(data, i, j); } else { break; } } //把分解值放到合适的位置,j的位置存放的是最后一个比分界值小的数 swap(data, start, j); //递归左右两个序列,j这个位置是上一趟的分界值,已经放到了适当的位置了,所有不需要再排序 System.out.println(java.util.Arrays.toString(data)); fastSort(data, start, j-1); fastSort(data, j+1, end); } } public static void main(String[] args) { DataWrap[] data = { new DataWrap(19, ""), new DataWrap(45, ""), new DataWrap(16, ""), new DataWrap(21, "*"), new DataWrap(23, ""), new DataWrap(21, ""), new DataWrap(30, ""),}; System.out.println("排序之前"); System.out.println(java.util.Arrays.toString(data)); System.out.println("开始排序"); fastSort(data,0,data.length-1); System.out.println("排序完成"); System.out.println(java.util.Arrays.toString(data)); } }
package test.java.sort.Util; /** * 2017-5-15 定义一个数据包装类 * @author tom */ public class DataWrap implements Comparable<DataWrap> { int data; String flag; public DataWrap(int data, String flag) { this.data =http://www.mamicode.com/ data; this.flag = flag; } @Override public String toString() { return data + flag; } // 如果当前data大于dw,返回1;小于和等于返回数值不是1 @Override public int compareTo(DataWrap dw) { return this.data > dw.data ? 1 : (this.data =http://www.mamicode.com/= dw.data ? 0 : -1); } }
程序运行结果:
排序之前
[19, 45, 16, 21*, 23, 21, 30]
开始排序
[16, 19, 45, 21*, 23, 21, 30]
[16, 19, 30, 21*, 23, 21, 45]
[16, 19, 21, 21*, 23, 30, 45]
[16, 19, 21, 21*, 23, 30, 45]
[16, 19, 21, 21*, 23, 30, 45]
排序完成
[16, 19, 21, 21*, 23, 30, 45]
快速排序不是一种稳定的排序算法。
排序算法之快速排序