原理

image.png

算法实现

  1. /**
  2. * 将数组分为两部分,一部分是有序的,一部分是无序的,每次从无序的里面拿出一个,
  3. * 与有序数组进行比较, 默认第一个是有序的,所以遍历从1开始
  4. * @param arr
  5. */
  6. public void sort(int[] arr) {
  7. for (int i = 1; i < arr.length; i++) {
  8. int cur = i;
  9. while (cur>=1 && arr[cur]<arr[cur-1]){
  10. ArrayUtil.swap(arr,cur-1,cur);
  11. cur--;
  12. }
  13. }
  14. }
  15. public class ArrayUtil {
  16. public static void swap(int arr[], int left, int right){
  17. if(arr.length==0 || arr.length-1<left || arr.length-1<right){
  18. return;
  19. }
  20. int tmp = arr[left];
  21. arr[left] = arr[right];
  22. arr[right] = tmp;
  23. }
  24. }

image.png

image.png

优化

优化交换的次数
image.png

  1. public void insertSort2(int[] arr){
  2. for (int i = 1; i <arr.length ; i++) {
  3. int temp = arr[i];
  4. int cur = i;
  5. while (cur>0 && arr[cur-1]>temp){
  6. //将比当前元素大的完后挪
  7. arr[cur] = arr[cur-1];
  8. cur--;
  9. }
  10. arr[cur] = temp;
  11. }

优化比较次数
image.png
image.png
image.png

  1. public void insertSort3(int[] arr){
  2. for (int i = 1; i <arr.length ; i++) {
  3. //二分查找待插入的下标位置
  4. int insertIndex = searchFirstMaxIndex(arr, i);
  5. //挪动元素,挪动的元素范围为[insertIndex, i)
  6. int temp = arr[i];
  7. for (int j=i-1;j>=insertIndex;j--){
  8. arr[j+1] = arr[j];
  9. }
  10. arr[insertIndex] = temp;
  11. }
  12. }
  13. /**
  14. * 查询第一个大于当前元素的数组下标
  15. * 查询的范围为[0,index)
  16. *
  17. * @param arr 原数组
  18. * @param index 待插入的元素下标
  19. * @return
  20. */
  21. public int searchFirstMaxIndex(int[] arr,int index){
  22. if(arr == null || arr.length<=0) {
  23. return -1;
  24. }
  25. int begin = 0; int end = index;
  26. while (begin<end){
  27. int mid = begin +((end-begin)>>1);
  28. //如果>=mid,则在右边
  29. if(arr[mid]<=arr[index]){
  30. begin = mid+1;
  31. }else{
  32. end = mid;
  33. }
  34. }
  35. return end;
  36. }