概述
插入排序根据实现方法,又分为直接插入排序(Straight Insertion Sort)和希尔排序(采用分治,Shell`s Sort)。二者时间复杂度、空间复杂度及稳定性如下:
1.直接插入排序(Straight Insertion Sort)
基本思想:
将一个记录插入到已排序好的有序表中,从而得到一个新的记录数增1的有序表。即:先将序列的第1个记录看成是一个有序的子序列,然后从第2个记录逐个进行插入,直至整个序列有序为止。插入排序比较适合用于“少量元素的数组”。
要点:
设立哨兵,作为临时存储和判断数组边界之用。
直接插入排序示例:
如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。所以,相等元素的前后顺序没有改变,从原无序序列出去的顺序就是排好序后的顺序,所以插入排序是稳定的。
Java代码实现:
package sort;
import java.util.Scanner;
public class StraightInsertionSort {
static int N = 1000;
static int[] so = new int[N];
static int length = 0;
public static void main(String[] args) {
StraightInsertionSort sis = new StraightInsertionSort();
sis.Input();
sis.Sort();
sis.Output();
}
// 系统输入数组
private void Input() {
Scanner sc = new Scanner(System.in);
System.out.println("Please input your data:");
String tmp = sc.nextLine();
String str[] = tmp.split(" ");
length = str.length;
for (int i = 0; i < length; i++) {
so[i] = Integer.parseInt(str[i]);
}
sc.close();
}
// 排序
private void Sort() {
for (int i = 1; i < length; i++) {
int x = so[i];
int j = i - 1;
while (j >= 0 && x < so[j]) {
so[j + 1] = so[j];
j--;
}
so[j + 1] = x;
}
}
// 输出排序后的数组
private void Output() {
for (int i = 0; i < length; i++) {
System.out.print(so[i] + " ");
}
}
}
2.希尔排序(Shell`s Sort)
希尔排序是1959 年由D.L.Shell 提出来的,相对直接排序有较大的改进。希尔排序又叫缩小增量排序
基本思想:
先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。
操作方法:
选择一个增量序列t1,t2,…,tk,其中ti>tj,tk=1;
按增量序列个数k,对序列进行k 趟排序;
每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m 的子序列,分别对各子表进行直接插入排序。仅增量因子为1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。
希尔排序的示例:
Java代码实现:
package sort;
import java.util.Scanner;
public class ShellSort {
static int N = 1000;
static int[] so = new int[N];
static int length = 0;
public static void main(String[] args) {
ShellSort ss = new ShellSort();
ss.Input();
ss.Sort();
ss.Output();
}
// 系统输入数组
private void Input() {
Scanner sc = new Scanner(System.in);
System.out.println("Please input your data:");
String tmp = sc.nextLine();
String str[] = tmp.split(" ");
length = str.length;
for (int i = 0; i < length; i++) {
so[i] = Integer.parseInt(str[i]);
}
sc.close();
}
// 排序
private void Sort() {
int i, j, gap;
for (gap = length / 2; gap > 0; gap /= 2) { // gap:分组
for (i = 0; i < gap; i++) {
for (j = i + gap; j < length; j += gap) { // 插入排序
int x = so[j];
int k = j - gap;
while (k >= 0 && x < so[k]) {
so[k + gap] = so[k];
k -= gap;
}
so[k + gap] = x;
}
}
}
}
// 输出排序后的数组
private void Output() {
for (int i = 0; i < length; i++) {
System.out.print(so[i] + " ");
}
}
}
参考:http://blog.csdn.net/xiazdong
参考:http://blog.csdn.net/hguisu/article/details/7776068
参考:百度百科及算法导论