学习来源:日撸 Java 三百行(41-50天,查找与排序)_闵帆的博客——CSDN博客
在前面的基础上加上一些常用的其他排序
1. 快速排序
交换排序中最主要的就是冒泡排序和快速排序。
快速排序的基本思想是居于分治法,在待排序表中任取一个元素作为基准pivot,通过一趟排序将待排序表划分为两个独立部分,其中一部分元素全都小于pivot,另一部分元素都大于pivot,此时作为基准的元素就处于其最终的位置上。然后分别对剩余的两个部分重复上述操作直到每个部分为空或仅有一个元素,此时所有元素都在其最终的位置上,整个表有序。
快速排序是平均性能最优的算法,但在对基本有序的表进行排序时,快速排序的效率并不高。
/**
*********************
* 快速排序
*
* @param paraStart 开始下标
* @param paraEnd 结束下标
*********************
*/
public void quickSortRecursive(int paraStart, int paraEnd) {
//无需移动
if (paraStart >= paraEnd) {
return;
}//Of if
int tempPivot = data[paraEnd].key;
DataNode tempNodeForSwap;
int tempLeft = paraStart;
int tempRight = paraEnd - 1;
//寻找中间节点的位置,同时将小的元素移到左边,将大的元素移到右边
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) {
//交换元素
//System.out.println("Swapping " + tempLeft + " and " + tempRight);
tempNodeForSwap = data[tempLeft];
data[tempLeft] = data[tempRight];
data[tempRight] = tempNodeForSwap;
} else {
break;
}//Of if
}//Of while
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
/**
*********************
* 快速排序
*********************
*/
public void quickSort() {
quickSortRecursive(0, length - 1);
}//Of quickSort
/**
*********************
* 快排方法测试
*********************
*/
public static void quickSortTest() {
int[] tempUnsortedKeys = { 1, 3, 12, 10, 5, 7, 9 };
String[] tempContents = { "if", "then", "else", "switch", "case", "for", "while" };
DataArray tempDataArray = new DataArray(tempUnsortedKeys, tempContents);
System.out.println(tempDataArray);
tempDataArray.quickSort();
System.out.println("Result\r\n" + tempDataArray);
}//Of quickSortTest
运行结果
2. 选择排序
选择排序的基本思想是每一趟(第i趟)在未排序的元素中选择关键字最小的元素作为有序序列的第i个元素,直到第n-1趟,所有元素有序。
/**
*********************
* 选择排序
*********************
*/
public void selectionSort() {
DataNode tempNode;
int tempIndexForSmallest;
for (int i = 0; i < length - 1; i++) {
//初始化
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
data[tempIndexForSmallest] = data[i];
data[i] = tempNode;
}//Of for i
}//Of selectionSort
/**
*********************
* 选择排序方法测试
*********************
*/
public static void selectionSortTest() {
int[] tempUnsortedKeys = { 5, 3, 6, 10, 7, 1, 9 };
String[] tempContents = { "if", "then", "else", "switch", "case", "for", "while" };
DataArray tempDataArray = new DataArray(tempUnsortedKeys, tempContents);
System.out.println(tempDataArray);
tempDataArray.selectionSort();
System.out.println("Result\r\n" + tempDataArray);
}//Of selectionSortTest
运行结果
3. 堆排序
堆排序借助完全二叉树实现,关键在于建堆和调整堆的过程。
/**
*********************
* 堆排序
*********************
*/
public void heapSort() {
DataNode tempNode;
//初始化堆
for (int i = length / 2 - 1; i >= 0; i--) {
adjustHeap(i, length);
}//Of for i
System.out.println("The initial heap: " + this + "\r\n");
//调整堆
for (int i = length - 1; i > 0; i--) {
tempNode = data[0];
data[0] = data[i];
data[i] = tempNode;
adjustHeap(0, i);
System.out.println("Round " + (length - i) + ": " + this + '\n');
}//Of for i
}//Of heapSort
/**
*********************
* 调整堆
*
* @param paraStart 开始下标
* @param paraLength 要调整的序列长
*********************
*/
public void adjustHeap(int paraStart, int paraLength) {
DataNode tempNode = data[paraStart];
int tempParent = paraStart;
int tempKey = data[paraStart].key;
for (int tempChild = paraStart * 2 + 1; tempChild < paraLength; tempChild = tempChild * 2 + 1) {
//右孩子更大
if (tempChild + 1 < paraLength) {
if (data[tempChild].key < data[tempChild + 1].key) {
tempChild++;
}//Of if
}//Of if
System.out.println("The parent position is " + tempParent + " and the child is " + tempChild);
if (tempKey < data[tempChild].key) {
//孩子更大
data[tempParent] = data[tempChild];
System.out.println("Move " + data[tempChild].key + " to position " + tempParent);
tempParent = tempChild;
} else {
break;
}//Of if
}//Of for tempChild
data[tempParent] = tempNode;
System.out.println("Adjust " + paraStart + " to " + paraLength + ": " + this);
}//Of adjustHeap
/**
*********************
* 堆排序方法测试
*********************
*/
public static void heapSortTest() {
int[] tempUnsortedKeys = { 5, 3, 6, 10, 7, 1, 9 };
String[] tempContents = { "if", "then", "else", "switch", "case", "for", "while" };
DataArray tempDataArray = new DataArray(tempUnsortedKeys, tempContents);
System.out.println(tempDataArray);
tempDataArray.heapSort();
System.out.println("Result\r\n" + tempDataArray);
}//Of heapSortTest
运行结果
(建堆)
(调整堆一趟)
结果
4. 归并排序
“归并”是将两个或两个以上的有序表组合成一个新的有序表。这里用的是二路归并。
/**
*********************
* 归并排序
*********************
*/
public void mergeSort() {
//当前行
int tempRow;
//分组数
int tempGroups;
//0或者1
int tempActualRow;
int tempNextRow = 0;
int tempGroupNumber;
int tempFirstStart, tempSecondStart, tempSecondEnd;
int tempFirstIndex, tempSecondIndex;
int tempNumCopied;
//输出表
for (int i = 0; i < length; i++) {
System.out.print(data[i]);
}//Of for i
System.out.println();
DataNode[][] tempMatrix = new DataNode[2][length];
//复制元素
for (int i = 0; i < length; i++) {
tempMatrix[0][i] = data[i];
}//Of for i
//排序
tempRow = -1;
for (int tempSize = 1; tempSize <= length; tempSize *= 2) {
// Reuse the space of the two rows.
tempRow++;
System.out.println("Current row = " + tempRow);
tempActualRow = tempRow % 2;
tempNextRow = (tempRow + 1) % 2;
tempGroups = length / (tempSize * 2);
if (length % (tempSize * 2) != 0) {
tempGroups++;
}//Of if
System.out.println("tempSize = " + tempSize + ", numGroups = " + tempGroups);
for (tempGroupNumber = 0; tempGroupNumber < tempGroups; tempGroupNumber++) {
tempFirstStart = tempGroupNumber * tempSize * 2;
tempSecondStart = tempGroupNumber * tempSize * 2 + tempSize;
if (tempSecondStart > length - 1) {
//复制前一个部分
for (int i = tempFirstStart; i < length; i++) {
tempMatrix[tempNextRow][i] = tempMatrix[tempActualRow][i];
}//Of for i
continue;
}//Of if
tempSecondEnd = tempGroupNumber * tempSize * 2 + tempSize * 2 - 1;
if (tempSecondEnd > length - 1) {
tempSecondEnd = length - 1;
}//Of if
System.out.println("Trying to merge [" + tempFirstStart + ", " + (tempSecondStart - 1) + "] with [" + tempSecondStart + ", " + tempSecondEnd + "]");
tempFirstIndex = tempFirstStart;
tempSecondIndex = tempSecondStart;
tempNumCopied = 0;
while ((tempFirstIndex <= tempSecondStart - 1)
&& (tempSecondIndex <= tempSecondEnd)) {
if (tempMatrix[tempActualRow][tempFirstIndex].key <= tempMatrix[tempActualRow][tempSecondIndex].key) {
tempMatrix[tempNextRow][tempFirstStart + tempNumCopied] = tempMatrix[tempActualRow][tempFirstIndex];
tempFirstIndex++;
System.out.println("copying " + tempMatrix[tempActualRow][tempFirstIndex]);
} else {
tempMatrix[tempNextRow][tempFirstStart + tempNumCopied] = tempMatrix[tempActualRow][tempSecondIndex];
System.out.println("copying " + tempMatrix[tempActualRow][tempSecondIndex]);
tempSecondIndex++;
}//Of if
tempNumCopied++;
}//Of while
while (tempFirstIndex <= tempSecondStart - 1) {
tempMatrix[tempNextRow][tempFirstStart + tempNumCopied] = tempMatrix[tempActualRow][tempFirstIndex];
tempFirstIndex++;
tempNumCopied++;
}//Of while
while (tempSecondIndex <= tempSecondEnd) {
tempMatrix[tempNextRow][tempFirstStart + tempNumCopied] = tempMatrix[tempActualRow][tempSecondIndex];
tempSecondIndex++;
tempNumCopied++;
}//Of while
}//Of for groupNumber
System.out.println("Round " + tempRow);
for (int i = 0; i < length; i++) {
System.out.print(tempMatrix[tempNextRow][i] + " ");
}//Of for j
System.out.println();
}//Of for tempStepSize
data = tempMatrix[tempNextRow];
}//Of mergeSort
/**
*********************
* 归并排序方法测试
*********************
*/
public static void mergeSortTest() {
int[] tempUnsortedKeys = { 5, 3, 6, 10, 7, 1, 9 };
String[] tempContents = { "if", "then", "else", "switch", "case", "for", "while" };
DataArray tempDataArray = new DataArray(tempUnsortedKeys, tempContents);
System.out.println(tempDataArray);
tempDataArray.mergeSort();
System.out.println(tempDataArray);
}//Of mergeSortTest
运行结果