1.插入排序算法
/***
*
* @author xiaoo_gan
* 排序算法:插入排序算法
*
* 特点:
* 1.当前索引左边的所有元素都是有序的,但它们的最终位置还不确定,
* 为了给更小(大)的元素腾出空间,它们可能会被移动。
* 但是当索引到达数组的右端时,数组排序就完成。
* 2.和选择排序不同的是,插入排序所需的时间取决与输入元素的初始顺序。
* 3.时间复杂度:
* 平均: 比较次数: N*N/4 交换次数: N*N/4
* 最坏: 比较次数: N*N/2 交换次数: N*N/2 (逆序)
* 最好: 比较次数: N-1 交换次数: 0 (有序)
*
*
* 测试:
* input: S O R T E X A M P L E (升序)
* output: A E E L M O P R S T X
*/
public class Insertion {
// 排序算法实现
public static void sort(Comparable[] a) {
int N = a.length;
for (int i = 1; i < N; i++) {
for (int j = i; j > 0 && less(a[j], a[j-1]); j--) {//(升序)
//for (int j = i; j > 0 && less(a[j-1], a[j]); j--) {//(降序)
exch(a, j, j-1);
}
}
}
// 判断第一个数是否大于第二个数
private static boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
}
// 交换两个数的位置
private static void exch(Comparable[] a, int i, int j) {
Comparable t = a[i];
a[i] = a[j];
a[j] = t;
}
// 打印数组
private static void show(Comparable[] a) {
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
System.out.println();
}
// 判断是否已排序
public static boolean isSorted(Comparable[] a) {
for (int i = 0; i < a.length; i++) {
if (less(a[i], a[i-1])) {
return false;
}
}
return true;
}
public static void main(String[] args) {
String[] a = {"S", "O", "R", "T", "E", "X", "A", "M", "P", "L", "E"};
sort(a); //排序
assert isSorted(a); //判断数组是否有序
show(a); //打印数组
}
}
2.插入排序算法的轨迹图
/***
*
* @author xiaoo_gan
* 插入排序的轨迹图
* 2.1.4 按照算法Insertion给出插入排序是如何将数组 E A S Y Q U E S T I O N 排序的。
*/
public class TraceInsertion {
private static void header(String[] a) {
int N = a.length;
StdDraw.setPenColor(StdDraw.BLACK);
StdDraw.text(N / 2, -3, "a[ ]");
StdDraw.text(-2.5, -2, "i");
StdDraw.text(-1.25, -2, "min");
for (int i = 0; i < N; i++) {
StdDraw.text(i, -2, i + "");
}
StdDraw.setPenColor(StdDraw.BOOK_RED);
StdDraw.line(-3, -1.65, N - 3, -1.65);
StdDraw.setPenColor(StdDraw.BLACK);
for (int i = 0; i < N; i++) {
StdDraw.text(i, -1, a[i]);
}
}
public static void sort(String[] a) {
int N = a.length;
for (int i = 1; i < N; i++) {
int min = i;
for (int j = i-1; j >= 0; j--) {
if (less(a[i], a[j])) {
min = j;
}
}
for (int j = i; j > min; j--) {
exch(a, j, j-1);
}
draw(a, i, i, min);
}
}
private static void draw(String[] a, int row, int ith, int min) {
StdDraw.setPenColor(StdDraw.BLACK);
StdDraw.text(-2.5, row - 1, row + "");
StdDraw.text(-1.25, row - 1, min + "");
for (int i = 0; i < a.length; i++) {
if (i == min) {
StdDraw.setPenColor(StdDraw.BOOK_RED);
} else if (i > min && i <= ith) {
StdDraw.setPenColor(StdDraw.BLACK);
} else {
StdDraw.setPenColor(StdDraw.LIGHT_GRAY);
}
StdDraw.text(i, row - 1, a[i]);
}
}
private static boolean less(String a, String b) {
return (a.compareTo(b) < 0);
}
private static void exch(String[] a, int i, int j) {
String swap = a[i];
a[i] = a[j];
a[j] = swap;
}
private static void footer(String[] a) {
StdDraw.setPenColor(StdDraw.BLACK);
for (int i = 0; i < a.length; i++) {
StdDraw.text(i, a.length - 1, a[i]);
}
}
public static void main(String[] args) {
String s = args[0];
int N = s.length();
String[] a = new String[N];
for (int i = 0; i < N; i++) {
a[i] = s.substring(i, i + 1);
}
StdDraw.setCanvasSize(30 * (N + 3), 30 * (N + 3));
StdDraw.setXscale(-3, N + 1);
StdDraw.setYscale(N + 1, -3);
StdDraw.setFont(new Font("SansSerif", Font.PLAIN, 13));
header(a);
sort(a);
footer(a);
}
}