插入排序
有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这个时候就要用到一种新的排序方法——插入排序法,插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为O(n^2)。是稳定的排序方法。插入算法把要排序的数组分成两部分:第一部分包含了这个数组的所有元素,但将最后一个元素除外(让数组多一个空间才有插入的位置),而第二部分就只包含这一个元素(即待插入元素)。在第一部分排序完成后,再将这个最后元素插入到已排好序的第一部分中。
插入排序的基本思想是:每步将一个待排序的记录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。
时间复杂度
如果目标是把n个元素的序列升序排列,那么采用插入排序存在最好情况和最坏情况。最好情况就是,序列已经是升序排列了,在这种情况下,需要进行的比较操作需(n-1)次即可。最坏情况就是,序列是降序排列,那么此时需要进行的比较共有n(n-1)/2次。插入排序的赋值操作是比较操作的次数加上 (n-1)次。平均来说插入排序算法的时间复杂度为O(n^2)。因而,插入排序不适合对于数据量比较大的排序应用。但是,如果需要排序的数据量很小,例如,量级小于千,那么插入排序还是一个不错的选择。
稳定性
插入排序是在一个已经有序的小序列的基础上,一次插入一个元素。当然,刚开始这个有序的小序列只有1个元素,就是第一个元素。比较是从有序序列的末尾开始,也就是想要插入的元素和已经有序的最大者开始比起,如果比它大则直接插入在其后面,否则一直往前找直到找到它该插入的位置。如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。所以,相等元素的前后顺序没有改变,从原无序序列出去的顺序就是排好序后的顺序,所以插入排序是稳定的。
import java.util.Arrays;public class Insert_Sort {public static void main(String[] args) {int[] a = {21,25,49,25,16,8};insertSort1(a);System.out.println(Arrays.toString(a));}//普通插入排序public static void insertSort(int[] a) {for (int i = 0; i < a.length-1; i++) {//躺数,每趟插入第i+1个元素---待插入的数int temp = a[i+1];//先把待插入的元素备份int j = i;for (; j>-1; j--) {//待插入的元素的前面一个元素开始找,if (temp<a[j]) {//如果比待插入的元素大则该元素往后移动一个位置a[j+1] = a[j];}else{//否则退出 因为第j个元素一定不大于待插入的元素break;}}a[j+1] = temp;//此时待插入的元素就插在第j元素后面}}//优化插入排序:查找过程采用二分思想public static void insertSort1(int[] a) {for (int i = 0; i < a.length-1; i++) {int temp = a[i+1];int left = 0;int right = i;int mid ;while(left<=right){//二分查找mid = (left+right)/2;if (temp>a[mid]) {left = mid+1;}else{right = mid - 1;}}for (int j = i; j >right; j--) {a[j+1] = a[j];}a[right+1] = temp;}}
}