持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第24天,点击查看活动详情
快速排序
基本思路
需要一个基准值,在这个基准值的右边的数都比这个基准值大,左边的数都比这个基准值小。一趟排序就可以确定一个数的最终位置,这个快速排序是在两头同时进行比较,若左边指针high若大于基准值,则移动指针,若小于基准值,则low开始移动指针,若大于基准值,则交换数据.下面模拟了快速排序的过程。
思考
快速排序,会在左右两边各设置一个指针low和hight,上面模拟的时候是从hight开始,则是否可以从low开始呢?hight是遇到比基准值小的数会停下来,low是遇到基准值比自己大的会停下来,所以low与hight相遇时需要交换基准值,而相遇时的那个值可能大于基准值(因为low先移动指针,而low是找最大的值停下来),在最后与基准值交换数据时,会把比基准值较大的数据交换,导致不满足左边小右边大。最后的递归也将出错。(这里模拟的是从小到大的升序排序)
递归思想
每一趟排序后就会有基准值的左右两边,对左右两边又进行同样的快速排序操作操作,所以这个是有递归思想在里面的,用递归算法解决。
代码实现
方法中的两个递归分别是对基准值左边和右边分别又进行快速排序
quickSortRecursive(paraStart, tempLeft - 1);
quickSortRecursive(tempLeft + 1, paraEnd);
(这里先移动指针是移动的左边,因为我们可以看到他选的基准值是待排序的最后一个)
public void quickSortRecursive(int paraStart, int paraEnd) {
// Nothing to sort.
if (paraStart >= paraEnd) {
return;
} // Of if
int tempPivot = data[paraEnd].key;
DataNode tempNodeForSwap;
int tempLeft = paraStart;
int tempRight = paraEnd - 1;
// Find the position for the pivot.At the same time move smaller elements to the left and bigger one to the right.
while (true) {
//左边指针要先移动
while ((data[tempLeft].key < tempPivot) && (tempLeft < tempRight)) {
tempLeft++;
}
while ((data[tempRight].key >= tempPivot) && (tempLeft < tempRight)) {
tempRight--;
}
if (tempLeft < tempRight) {
// Swap.
System.out.println("Swapping " + tempLeft + " and " + tempRight);
tempNodeForSwap = data[tempLeft];
data[tempLeft] = data[tempRight];
data[tempRight] = tempNodeForSwap;
} else {
break;
}
}
// Swap
if (data[tempLeft].key > tempPivot) {
tempNodeForSwap = data[paraEnd];
data[paraEnd] = data[tempLeft];
data[tempLeft] = tempNodeForSwap;
} else {
tempLeft++;
}
System.out.print("From " + paraStart + " to " + paraEnd + ": ");
System.out.println(this);
quickSortRecursive(paraStart, tempLeft - 1);
quickSortRecursive(tempLeft + 1, paraEnd);
}// Of quickSortRecursive
测试结果:
-------quickSortTest-------
I am a data array with 7 items.
(1, if) (3, then) (12, else) (10, switch) (5, case) (7, for) (9, while)
Swapping 2 and 5
Swapping 3 and 4
From 0 to 6: I am a data array with 7 items.
(1, if) (3, then) (7, for) (5, case) (9, while) (12, else) (10, switch)
From 0 to 3: I am a data array with 7 items.
(1, if) (3, then) (5, case) (7, for) (9, while) (12, else) (10, switch)
From 0 to 1: I am a data array with 7 items.
(1, if) (3, then) (5, case) (7, for) (9, while) (12, else) (10, switch)
From 5 to 6: I am a data array with 7 items.
(1, if) (3, then) (5, case) (7, for) (9, while) (10, switch) (12, else)
Result
I am a data array with 7 items.
(1, if) (3, then) (5, case) (7, for) (9, while) (10, switch) (12, else)
总结
今天学习了快速排序,快速排序要注意的是那个指针先移动。其次是对比昨天学习的冒泡排序,冒泡排序是从一边开始,并且交换的是相邻两个元素,他也会确定一个最终位置,但是这个最终位置是从下到上依次确定(或从上到下),而快速排序,他也是交换数据,但是他是两边同时开始比较,每次也会确定一个数的最终位置,但是这个位置并不是有规律的,需要结合排序的数据来看,相比冒泡,快速排序的基准值要选好才是关键。