Java 查找与排序(二)
文章目录
学习来源: 日撸 Java 三百行(41-50天,查找与排序)
一、插入排序
- 插入排序是简单直接的排序方式之一. 代码非常短.
- 每次保证前 i 个数据是有序的.
- 先做简单的事情 (第 1 轮最多有 1 次移动), 再做麻烦的事情 (最后一轮最多有n − 1次移动).
- 下标 0 的数据为岗哨, 与 41 天内容同理. 比其它排序方式多用一个空间.
- 又见 this.
- tempNode 只分配了引用 (指针) 的空间, 并未 new.
代码如下:
package datastructure.search;
/**
*
* @author Ling Lin E-mail:linling0.0@foxmail.com
*
* @version 创建时间:2022年5月1日 下午4:09:47
*
*/
public class DataArray {
/**
* An inner class for data nodes. The text book usually use an int value to
* represent the data. I would like to use a key-value pair instead.
*/
class DataNode {
// The key.
int key;
// The data content.
String content;
/**
*********************
* The first constructor.
*********************
*/
DataNode(int paraKey, String paraContent) {
key = paraKey;
content = paraContent;
}// Of the first constructor
/**
* Overrides the method claimed in Object, the superclass of any class.
*/
@Override
public String toString() {
return "(" + key + ", " + content + ") ";
}// Of toString
}// Of class DataNode
// The data array.
DataNode[] data;
// The length of the data array.
int length;
/**
*********************
* The first constructor.
*
* @param paraKeyArray
* The array of the keys.
* @param paraContentArray
* The array of contents.
*********************
*/
public DataArray(int[] paraKeyArray, String[] paraContentArray) {
length = paraKeyArray.length;
data = new DataNode[length];
for (int i = 0; i < length; i++) {
data[i] = new DataNode(paraKeyArray[i], paraContentArray[i]);
} // Of for i
}// Of the first constructor
/**
* Overrides the method claimed in Object, the superclass of any class.
*/
@Override
public String toString() {
String resultString = "I am a data array with " + length + " items.\r\n";
for (int i = 0; i < length; i++) {
resultString += data[i] + " ";
} // Of for i
return resultString;
}// Of toString
/**
* Insertion sort. data[0] does not store a valid data. data[0].key should
* be smaller than any valid key.
*/
public void insertionSort() {
DataNode tempNode;
int j;
for (int i = 2; i < length; i++) {
tempNode = data[i];
// Find the position to insert.
// At the same time, move other nodes.
for (j = i - 1; data[j].key > tempNode.key; j--) {
data[j + 1] = data[j];
} // Of for j
// Insert.
data[j + 1] = tempNode;
System.out.println("Round " + (i - 1));
System.out.println(this);
} // Of for i
}// Of insertionSort
/**
* Test the method.
*/
public static void insertionSortTest() {
int[] tempUnsortedKeys = { -100, 8, 7, 6, 5, 4, 3, 2 };
String[] tempContents = { "null", "if", "then", "else", "switch", "case", "for", "while" };
DataArray tempDataArray = new DataArray(tempUnsortedKeys, tempContents);
System.out.println(tempDataArray);
tempDataArray.insertionSort();
System.out.println("Result\r\n" + tempDataArray);
}// Of insertionSortTest
/**
* The entrance of the program.
*
* @param args
* Not used now.
*/
public static void main(String args[]) {
System.out.println("\r\n-------insertionSortTest-------");
insertionSortTest();
}// Of main
}// Of class DataArray
运行结果:
二、希尔排序
- 多达 4 重循环, 但时间复杂度只有 O(n2). 多次排序反而减少了平均排序时间. 神奇的脑回路.
- 有了昨天的程序铺垫, 本程序写起来也不难.
- 岗哨的个数与最初的步长相关, 我们的程序中为 5. 简便起见我就没用了.
- 可以改变 tempJumpArray.
- 测试用例多用了几个数据, 便于观察.
package datastructure.search;
/**
*
* @author Ling Lin E-mail:linling0.0@foxmail.com
*
* @version 创建时间:2022年5月1日 下午4:09:47
*
*/
public class DataArray {
/**
* An inner class for data nodes. The text book usually use an int value to
* represent the data. I would like to use a key-value pair instead.
*/
class DataNode {
// The key.
int key;
// The data content.
String content;
/**
*********************
* The first constructor.
*********************
*/
DataNode(int paraKey, String paraContent) {
key = paraKey;
content = paraContent;
}// Of the first constructor
/**
* Overrides the method claimed in Object, the superclass of any class.
*/
@Override
public String toString() {
return "(" + key + ", " + content + ") ";
}// Of toString
}// Of class DataNode
// The data array.
DataNode[] data;
// The length of the data array.
int length;
/**
*********************
* The first constructor.
*
* @param paraKeyArray
* The array of the keys.
* @param paraContentArray
* The array of contents.
*********************
*/
public DataArray(int[] paraKeyArray, String[] paraContentArray) {
length = paraKeyArray.length;
data = new DataNode[length];
for (int i = 0; i < length; i++) {
data[i] = new DataNode(paraKeyArray[i], paraContentArray[i]);
} // Of for i
}// Of the first constructor
/**
* Overrides the method claimed in Object, the superclass of any class.
*/
@Override
public String toString() {
String resultString = "I am a data array with " + length + " items.\r\n";
for (int i = 0; i < length; i++) {
resultString += data[i] + " ";
} // Of for i
return resultString;
}// Of toString
/**
* Shell sort. We do not use sentries here because too many of them are
* needed.
*/
public void shellSort() {
DataNode tempNode;
int[] tempJumpArray = { 5, 3, 1 };
int tempJump;
int p;
for (int i = 0; i < tempJumpArray.length; i++) {
tempJump = tempJumpArray[i];
for (int j = 0; j < tempJump; j++) {
for (int k = j + tempJump; k < length; k += tempJump) {
tempNode = data[k];
// Find the position to insert.
// At the same time, move other nodes.
for (p = k - tempJump; p >= 0; p -= tempJump) {
if (data[p].key > tempNode.key) {
data[p + tempJump] = data[p];
} else {
break;
} // Of if
} // Of for p
// Insert.
data[p + tempJump] = tempNode;
} // Of for k
System.out.println("Round " + i);
System.out.println(this);
} // Of for j
} // Of for i
}// Of shellSort
/**
* Test the method.
*/
public static void shellSortTest() {
int[] tempUnsortedKeys = { 5, 3, 6, 10, 7, 1, 9, 12, 8, 4 };
String[] tempContents = { "if", "then", "else", "switch", "case", "for", "while", "throw", "until", "do" };
DataArray tempDataArray = new DataArray(tempUnsortedKeys, tempContents);
System.out.println(tempDataArray);
tempDataArray.shellSort();
System.out.println("Result\r\n" + tempDataArray);
}// Of shellSortTest
/**
* The entrance of the program.
*
* @param args
* Not used now.
*/
public static void main(String args[]) {
System.out.println("\r\n-------shellSortTest-------");
shellSortTest();
}// Of main
}// Of class DataArray