基本思想

每步将一个待排序的记录,按其顺序码大小插入到前面已经排序的字序列的合适位置(从后向前找到合适位置后),直到全部插入排序完为止。
直接插入排序 - 图1

代码实现

  1. public class DirectInsertionSort {
  2. public static void main(String[] args) {
  3. int[] a={49,38,65,97,76,13,27,49,78,34,12,64,1};
  4. System.out.println("排序之前:");
  5. for (int i = 0; i < a.length; i++) {
  6. System.out.print(a[i]+" ");
  7. }
  8. //直接插入排序
  9. for (int i = 1; i < a.length; i++) {
  10. //待插入元素
  11. int temp = a[i];
  12. int j;
  13. /*for (j = i-1; j>=0 && a[j]>temp; j--) {
  14. //将大于temp的往后移动一位
  15. a[j+1] = a[j];
  16. }*/
  17. for (j = i-1; j>=0; j--) {
  18. //将大于temp的往后移动一位
  19. if(a[j]>temp){
  20. a[j+1] = a[j];
  21. }else{
  22. break;
  23. }
  24. }
  25. a[j+1] = temp;
  26. }
  27. System.out.println();
  28. System.out.println("排序之后:");
  29. for (int i = 0; i < a.length; i++) {
  30. System.out.print(a[i]+" ");
  31. }
  32. }
  33. }
  1. /**
  2. * 插入排序<br/>
  3. * <ul>
  4. * <li>从第一个元素开始,该元素可以认为已经被排序</li>
  5. * <li>取出下一个元素,在已经排序的元素序列中从后向前扫描</li>
  6. * <li>如果该元素(已排序)大于新元素,将该元素移到下一位置</li>
  7. * <li>重复步骤3,直到找到已排序的元素小于或者等于新元素的位置</li>
  8. * <li>将新元素插入到该位置中</li>
  9. * <li>重复步骤2</li>
  10. * </ul>
  11. * @param numbers
  12. */
  13. public static void insertSort(int[] numbers) {
  14. int size = numbers.length, temp, j;
  15. for(int i=1; i<size; i++) {
  16. temp = numbers[i];
  17. for(j = i; j > 0 && temp < numbers[j-1]; j--)
  18. numbers[j] = numbers[j-1];
  19. numbers[j] = temp;
  20. }
  21. }
  1. public class InsertionSort<T extends Comparable<T>> {
  2. private InsertionSort() { }
  3. public static <T extends Comparable<T>> T[] sort(T[] unsorted) {
  4. int length = unsorted.length;
  5. for (int i = 1; i < length; i++) {
  6. sort(i, unsorted);
  7. }
  8. return unsorted;
  9. }
  10. private static <T extends Comparable<T>> void sort(int i, T[] unsorted) {
  11. for (int j = i; j > 0; j--) {
  12. T jthElement = unsorted[j];
  13. T jMinusOneElement = unsorted[j - 1];
  14. if (jthElement.compareTo(jMinusOneElement) < 0) {
  15. unsorted[j - 1] = jthElement;
  16. unsorted[j] = jMinusOneElement;
  17. } else {
  18. break;
  19. }
  20. }
  21. }
  22. }

总结

  1. 直接插入排序是稳定的排序。关于各种算法的稳定性分析可以参考 常用排序算法稳定性分析
  2. 文件初态不同时,直接插入排序所耗费的时间有很大差异。若文件初态为正序,则每个待插入的记录只需要比较一次就能够找到合适的位置插入,故算法的时间复杂度为O(n),这时最好的情况。若初态为反序,则第i个待插入记录需要比较i+1次才能找到合适位置插入,故时间复杂度为O(n2),这时最坏的情况。
  3. 直接插入排序的平均时间复杂度为O(n^2)。