快速排序
快速排序(Quick Sort),顾名思义,是目前为止在一般情况下效率最为高效的排序算法。当我看到它简单清晰的实现方式时,我深深的被这种人类思维产物所折服,绝对这是最为深刻的、美妙的排序算法。
它的思路为,随意取一个序列中的一个元素,将比该元素大和小的其他元素通过与之的一轮比较,分别放置到该元素的两侧,换言之,将该元素移动到一个位置,使得该位置处该元素的左右两侧分别满足小于等于和大于等于该元素。下一轮,执行递归,将小于等于该元素的元素和大于等于该元素的序列分别重复上述步奏,直到全部完成排序为止。
具体实现为,分别定义两个指针 i 和 j ,分别位于队列的起止位置。位于头位置的 i 指针从前向后扫描,如果该位置的元素小于等于该元素(选取的指标元素),那么 i 指针继续后移;反之,如果 i 指针所指位置处的元素大于该元素,那么将该元素与 i 指针位置处的元素互换。同样的,位于尾部的 j 指针从后向前扫描,如果该位置的元素大于等于该元素(选取的指标元素),那么 j 指针继续前移;反之,如果 j 指针所指位置处的元素小于该元素,那么将该元素与 j 指针位置处的元素互换。持续这种过程,直到 i 指针和 j 指针重合(相等为止),也即选取的指标元素到达了目标位置。每次换位后,指标元素的位置的某一侧一定满足小于等于该元素或大于等于该元素。这样,即完成了一轮的比较。递归这种过程,直到完成所有的排序。
下面是Java代码
/**
* 快速排序
* @param data
* @param high
* @param low
*/
private static void quickSort(int[] data, int low, int high) {
//分别定义从低到高比较的指针lowIndex和从高到低比较的指针highIndex
int lowIndex = low;
int highIndex = high;
//定义标记位的元素,可取 low - high 的任意一个
int markIndex = low;
while (lowIndex < highIndex) {
//一、如果指标元素(data[markIndex])前的元素小于等于指标元素
while (lowIndex < markIndex && data[lowIndex] <= data[markIndex]) {
lowIndex++;
}
//二、如果指标元素(data[markIndex])前的元素大于指标元素
if (lowIndex < markIndex && data[lowIndex] > data[markIndex]) {
swap(data, lowIndex, markIndex);
markIndex = lowIndex;
}
//三、如果指标元素(data[markIndex])后的元素大于等于指标元素
while (markIndex < highIndex && data[markIndex] <= data[highIndex]) {
highIndex--;
}
//四、如果指标元素(data[markIndex])后的元素小于指标元素
if (markIndex < highIndex && data[markIndex] > data[highIndex]) {
swap(data, markIndex, highIndex);
markIndex = highIndex;
}
}
//递归该过程
if (low < markIndex) {
//递归指标元素前的元素
quickSort(data, low, markIndex -1);
}
if (markIndex < high) {
//递归指标元素后的元素
quickSort(data, markIndex +1, high);
}
}
/**
* 数组内 i 坐标元素与 j 坐标元素互换
* @param data
* @param i
* @param j
*/
private static void swap(int[] data, int i, int j) {
int temp = data[i];
data[i] = data[j];
data[j] = temp;
}
该方法入参分别为整形数组data,起始坐标 0 和末尾坐标 data.length - 1.需要说明一下,其中 while 循环内的四部分相对独立,其顺序可任意颠倒,不会影响最终的结果。