数据结构排序算法之插入排序<一>
插入排序(Insertion sort)
是一种简单直观且稳定的排序算法。如果有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这个时候就要用到一种新的排序方法——插入排序法,插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为O(n^2)。是稳定的排序方法。插入算法把要排序的数组分成两部分:第一部分包含了这个数组的所有元素,但将最后一个元素除外(让数组多一个空间才有插入的位置),而第二部分就只包含这一个元素(即待插入元素)。在第一部分排序完成后,再将这个最后元素插入到已排好序的第一部分中。
插入排序的基本思想:
每步将一个待排序的记录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。
分类
emmmm这里只说三种主要的:
- 直接插入排序
- 折半插入排序(二分插入排序)
- 希尔排序(又称缩小增量排序)
1.直接插入排序
把n个待排元素分为有序区和无序区,开始时有序区中只包含1个元素,无序区中则包含n-1个元素,排序过程中每次都从无序区中取出第一个元素,将它插入到有序区中的适当位置,使之成为一个有序的表,重复n-1次可完成排序过程。
Java实现:
package priv.qcy.sort.insert;
public class InsertSort {
public static void insertSort(int[] a, int n) {
int i, j;
for (i = 1; i < n; i++) {
int temp = a[i];
for (j = i - 1; j >= 0 && a[j] > temp; j--) {
a[j + 1] = a[j];
}
a[j + 1] = temp;
}
}
public static void main(String[] args) {
int[] a = { 20, 40, 30, 10, 60, 50 };
System.out.print("排序前:");
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
System.out.println();
insertSort(a, a.length);
System.out.print("排序后:");
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
}
}
直接插入排序时间复杂度
直接插入排序的时间复杂度是O(N^2)。
假设被排序的数列中有N个数。遍历一趟的时间复杂度是O(N),而直接插入排序需要遍历N-1次。因此,直接插入排序的时间复杂度是O(N^2)。
直接插入排序稳定性
直接插入排序是稳定的算法,它满足稳定算法的定义。
算法稳定性 – 假设在数列中存在a[i]=a[j],若在排序之前,a[i]在a[j]前面;并且排序之后,a[i]仍然在a[j]前面。则这个排序算法是稳定的!
特点
- 也适用于链式存储结构
- 更适用于初始记录基本有序的情况(当N较大且无序时,此算法时间复杂度较高)