vlambda博客
学习文章列表

十大经典排序--插入排序及其优化

插入排序思路:


  • 从第一个元素开始,该元素可以认为已经被排序;

  • 取出下一个元素,在已经排序的元素序列中从后向前扫描;

  • 如果该元素(已排序)大于新元素,将该元素移到下一位置;

  • 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;

  • 将新元素插入到该位置后;

  • 重复步骤2~5。


为什么叫插入排序?

  • 因为它在不断地将未排序的元素插入已排序的元素序列当中


代码:

 1private static void sort(int[] arr) {
2    int size = arr.length;
3    for(int idx = 1; idx <= size -1; idx++) {
4        int end = idx;
5        //提前保留种子,因为数据移动会把原位置数刷新
6        int tmp = arr[end];
7        //将已排序的数中大于后面未排序的数 依次往后移动
8        while(end > 0 && tmp < arr[end -1]) {
9            arr[end] = arr[end-1];
10            end --;
11        }
12        //找到第一个小于未排序的数,插入
13        arr[end] = tmp;
14    }
15}

时间复杂度:O(n2/2)

空间复杂度:O(1)


优化:

思路:由于咱们知道插入是将一个未排序的元素在已排序的元素中找到一个合适的位置进行插入,那么这个在排序数组中找位置的过程就可以通过二分法来进行优化


代码:

 1private static void sort(int[] arr) {
2    int size = arr.length;
3    for (int idx = 1; idx <= size - 1; idx++) {
4        if (arr[idx] < arr[idx - 1]) {
5            int left = 0;
6            int right = idx - 1;
7            //提前保留种子,因为数据移动会把原位置数刷新
8            int end = arr[idx];
9            while (left <= right) {
10                int mid = left + ((right - left) / 2);
11                if (end < arr[mid]) {
12                    right = mid - 1;
13                } else {
14                    left = mid + 1;
15                }
16            }
17            //将已排序的数中大于后面未排序的数 依次往后移动
18            for (int j = idx; j > 0 && j > right + 1; j--) {
19                arr[j] = arr[j - 1];
20            }
21            //找到第一个小于未排序的数,插入
22            arr[right + 1] = end;
23        }
24    }
25}



以上仅是个人思路解法,觉得还不错欢迎点赞关注分享


往期精彩推荐