快速排序
描述:通过若干次划分的方法完成待排序序列的排序。划分是通过一次遍历用基准数将待排序序列分成两个部分,在基准数左边的部分都小于等于该基准数,在基准数右边的都大于等于该基准数。经过一次划分后,待排序序列划分成两个独立的序列,然后分别将划分过后的两个独立序列当做待排序序列再进行划分。
Java代码:
// 划分方法返回基准位置,
// 基准位置左边的所有值都小于等于基准位置的值,
// 基准位置右边的所有值都大于等于基准位置的值
public static int partition(int[] array,int low,int high) {
// 一般去第一个数为基准,如果使算法不受待排序序列影响,可以随机选取一个位置,将给位置与第一个位置交换。
// 此时,low指向的位置可以被覆盖
int tmp= array[low];
// 循环终止条件,当low和high相等时,表示当前只剩下一个元素,不需要比较
while (low< high) {
// 从右边向左边依次寻找第一个不满足大于基准数的位置
while (low< high && array[high] > tmp)
high--;
// 如果low位置小于high,将找到的第一个不满足大于基准数的位置high指向数组覆盖low指向的位置
// 此时,high指向的位置可以被覆盖
if (low< high)
array[low++] = array[high];
// 从左边向右边依次寻找第一个不满足小于等于基准数的位置
// 判断条件变为小于等于是因为待排序序列可能存在多个相等的值,
// 等于用于过滤多个相等的值,该等于也可以用在从右向左比较中,
// 但是从左到右和从右到左只能够有一个带等于号。
while (low< high && array[low] <= tmp)
low++;
// 如果low位置小于high,将找到的第一个不满足大于基准数的位置high指向数组覆盖low指向的位置
// 此时,low指向的位置可以被覆盖
if (low< high)
array[high--] = array[low];
}
// 每次循环入口是low位置可以被覆盖,第一次从右到左查找后high位置可以被覆盖,
// 第二次从左到右查找后low位置可以被覆盖,然后又到循环入口
// 循环中待比较序列位置为[low+1,high]
// 循环结束的low位置为最终基准的位置
array[low] = tmp;
// 返回最终的基准位置
return low;
}
// 通过划分方法,将待排序序列[sta,end]划分为两个待排序序列[sta,part-1]和[part+1,end]
public static void quickSort(int[] array,int sta,int end) {
if (sta>= 0 && sta < end) {
int part= partition(array, sta, end);
quickSort(array, sta, part - 1);
quickSort(array, part + 1,end);
}
}
测试代码:
public static boolean checkSort(int[] array) {
for (int i =1; i < array.length; i++) {
if(array[i] < array[i - 1])
return false;
}
return true;
}
public static void printArray(int[] array) {
for (int i =0; i < array.length; i++)
System.out.print(i+ ":" + array[i] + " ");
System.out.println();
}
public static void testQuickSort(int count,int size) {
Random random = new Random();
int[] array;
int length;
int errorCount = 0;
System.out.println("Start...");
while(count-- > 0) {
length = random.nextInt(size);
array = new int[length];
for (int i =0; i < length; i++)
array[i] = random.nextInt();
quickSort(array, 0, length -1);
if (!checkSort(array)){
errorCount++;
printArray(array);
}
}
System.out.println("End.The error QuickSort count is " + errorCount +" .");
}
测试报告:
运行程序testQuickSort(1000,100),即测试quickSort1000次,测试的数组长度在100以内的随机数组成的待排序序列。测试成功。
问题拓展:
快速排序中的划分方法partition可以用于:快速找出未知数组中第k大的数;快速找出未知数组中k个最大的数。
下载地址:
http://download.youkuaiyun.com/detail/ssuchange/6705807