插入排序是一种简单的排序算法,适用于少量的输入,如果只需要对几个元素进行排序,那么还是不错的解决方式,其算法相对简单。但是如果要处理大量的数据的时候,插入排序时很糟糕的;
原理如下所示:
假设有数组:int[] a = {5,6,1,2,7,8}
第一趟:5 6 1 2 7 8
第二趟:5 6 1 2 7 8
第三趟:1 5 6 2 7 8
第四趟:1 2 5 6 7 8
第五趟:1 2 5 6 7 8
第六趟:1 2 5 6 7 8
红色:代表已经排序;
代码如下
public class exp1 {
// 对int数组的插入排序算法
private static void sort(int[] a) {
for (int i = 1; i < a.length; i++) {
int j = i;
int temp = a[j];
for (; (j > 0 && (a[j] < a[j - 1])); j--) {
a[j] = a[j - 1];
a[j - 1] = temp;
}
}
}
// 更一般的做法是使用泛型
public static <AnyType extends Comparable<? super AnyType>> void sort1(
AnyType[] a) {
for (int i = 1; i < a.length; i++) {
int j = i;
AnyType temp = a[j];
for (; j > 0 && (a[j].compareTo(a[j-1])) < 0; j--) {
a[j] = a[j - 1];
a[j - 1] = temp;
}
}
}
public static void main(String[] args) {
int[] a = new int[] { 1, 3, 5, 7, 2, 9, 6 };
exp1.sort(a);
System.out.print(Arrays.toString(a));
Student[] p = new Student[5];
p[0] = new Student(5);
p[1] = new Student(1);
p[2] = new Student(2);
p[3] = new Student(3);
p[4] = new Student(9);
exp1.sort1(p);
System.out.print(Arrays.toString(p));
}
}
class Person {
private int height;
public Person(int height) {
this.height = height;
}
public int getHeight() {
return height;
}
public String toString() {
return Integer.toString(height);
}
}
class Student extends Person implements Comparable<Person> {
public Student(int height) {
super(height);
}
@Override
public int compareTo(Person s) {
// TODO Auto-generated method stub
if (getHeight() > s.getHeight()) {
return 1;
} else if (getHeight() == s.getHeight()) {
return 0;
} else {
return -1;
}
}
}
最坏时候的时间复杂度:O(N^2)
简单分析:大循环是N次迭代,二级循环最多执行j+1,得到总时间为:
为了更好的理解插入排序的运行时间,引入了逆序的概念;所谓的逆序就是数组中反序的一对元素;比如(8,5,9,2,6,3),公共有10个逆序;分别是:(8,5),(8,2)等。。
逆序代表交换的次数:所有假如逆序的个数是I,则运行时间应该为
O(N+I),所以如果逆序是O(N)个数,那么运行时间是线性的。