第 46 天: 快速排序
该方法的基本思想是:
- 1.先从数列中取出一个数作为基准数。
- 2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
- 3.再对左右区间重复第二步,直到各区间只有一个数。
这里我们选择的就是最后一个元素作为基准数
/**
*********************
* Quick sort recursively.
*
* @param paraStart The start index.
* @param paraEnd The end index.
*********************
*/
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++;
} // Of while
while ((data[tempRight].key >= tempPivot) && (tempLeft < tempRight)) {
tempRight--;
} // Of while
if (tempLeft < tempRight) {
// Swap.
System.out.println("Swapping " + tempLeft + " and " + tempRight);
tempNodeForSwap = data[tempLeft];
data[tempLeft] = data[tempRight];
data[tempRight] = tempNodeForSwap;
} else {
break;
} // Of if
} // Of while
// Swap
if (data[tempLeft].key > tempPivot) {
tempNodeForSwap = data[paraEnd];
data[paraEnd] = data[tempLeft];
data[tempLeft] = tempNodeForSwap;
} else {
tempLeft++;
} // Of if
System.out.print("From " + paraStart + " to " + paraEnd + ": ");
System.out.println(this);
quickSortRecursive(paraStart, tempLeft - 1);
quickSortRecursive(tempLeft + 1, paraEnd);
}// Of quickSortRecursive
其实在第一遍看的时候还没看懂,也是手动操作了一遍才理解到。里面还包括递归的思想,因为这个不是一次就能排出的,还是有”分而治之“的思想在里面。选择最后一个元素为基准数,所以tempRight = paraEnd - 1,之后进行循环,与tempPivot相比较,一个从左往右,一个从右往左,跳出循环的元素就交换,直到tempLeft>tempRight时,break,代表以tempPivot为准,小的在左,大的在右,然后就从小往大找出第一个大于tempPivot的元素,与tempPivot交换位置,即换到最后一个位置,这一步就确定好tempPivot的最终位置,然后再对左边,右边分开进行同样的操作。
这一步开始其实觉得可以不要else之后的东西,没懂起什么意思,但是想到如果基准元素就是最大的时候,就恍然大悟了。
第 47 天: 选择排序
选择排序是一种简单直观的排序算法,无论什么数据进去都是 O(n²) 的时间复杂度。所以用到它的时候,数据规模越小越好。
算法步骤:
首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
重复第二步,直到所有元素均排序完毕。
这里我们按照的从小到大的顺序:
/**
*********************
* Selection sort. All data are valid.
*********************
*/
public void selectionSort() {
DataNode tempNode;
int tempIndexForSmallest;
for (int i = 0; i < length - 1; i++) {
// Initialize.
tempNode = data[i];
tempIndexForSmallest = i;
for (int j = i + 1; j < length; j++) {
if (data[j].key < tempNode.key) {
tempNode = data[j];
tempIndexForSmallest = j;
} // Of if
} // Of for j
// Change the selected one with the current one.
data[tempIndexForSmallest] = data[i];
data[i] = tempNode;
} // Of for i
}// Of selectionSort
其中,tempIndexForSmallest用来标记,最后两步操作则是用来换位的,需要进行n−1 次比较才能获得最小的数据。总的来说比较基础。