Java~三种插入(insert)排序(直接插入排序、希尔(shell)排序、折半插入排序)

(稳定性就是俩个相同的元素排序前和排序后的相对位置,若相对位置不变,称为稳定)
直接插入排序-原理:(稳定)
整个区间被分为

  1. 有序区间 [0~index]
  2. 无序区间 (index~last]
    每次选择无序区间的第一个元素array[indxe],在有序区间内选择合适的位置插入。
    在这里插入图片描述
    实现:
 //降序直接插入排序
    public static void inDownSort(int[] array) {
        for (int index = 1; index < array.length; index++) {
            int tmp = array[index];
            for (int prevIndex = index - 1; prevIndex >= 0; prevIndex--) {
                //若要升序直接改为:tmp < array[prevIndex]
                if(tmp > array[prevIndex]) {
                    array[prevIndex + 1] = array[prevIndex];
                    array[prevIndex] = tmp;
                }else {
                    break;
                }
            }
        }
    }

性能分析:
时间复杂度:
最好O(n)
平均O(n^2)
最坏O(n^2)
空间复杂度:
O(1)

== 希尔排序-原理 :(不稳定)==
希尔排序法又称缩小增量法。希尔排序法的基本思想是:
先选定一个整数,把待排序文件中所有记录分成个组,所有距离为的记录分在同一组内,并对每一组内的记录进行排序。然后,取,重复上述分组和排序的工作。当到达=1时,所有记录在统一组内排好序。

  1. 希尔排序是对直接插入排序的优化。
  2. 当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就会很快。这样整体而言,可以达到优化的效果。我们实现后可以进行性能测试的对比。

在这里插入图片描述
实现:

 //降序希尔排序
    public static void shellDownSort(int[] array) {
        int gap = array.length / 2;
        while (gap >= 1) {
            for (int index = gap; index < array.length; index++) {
                int tmp = array[index];
                for(int prevIndex = index - gap; prevIndex >= 0; prevIndex -= gap) {
                    //若要升序直接改为:tmp < array[prevIndex]
                    if(tmp > array[prevIndex]) {
                        array[prevIndex + gap] = array[prevIndex];
                        array[prevIndex] = tmp;
                    }else {
                        break;
                    }
                }
            }
            gap /= 2;
        }
    }

性能分析:
时间复杂度:
最好O(n)
平均O(n^1.3)
最坏O(n^2)
空间复杂度:
O(1)

折半插入排序-原理:(稳定)
在有序区间选择数据应该插入的位置时,因为区间的有序性,可以利用折半查找的思想。
仔细来说就是在while循环里找到合适的位置放此时index下标的值。
然后将low下标之后indxe之前的元素往后移动一个位置,最后在low下标放tmp。

在这里插入图片描述

实现:

//降序折半插入排序
    public static void inHalfDownSort(int[] array) {
        for (int index = 1; index < array.length; index++) {
            int tmp = array[index];
            int low = 0;
            int high = index;
            //与折半查找不同的是,折半查找这里是low<=high
            while (low < high) {
                int mid = (low + high) / 2;
                //若要升序直接改为:array[mid] <= tmp
                if(array[mid] >= tmp) {
                    low += mid + 1;
                }else {
                     high = mid;
                }
            }
            for (int i = index; i > low; i--) {
                array[i] = array[i - 1];
            }
            array[low] = tmp;
        }
    }

执行结果:

[9, 8, 6, 4, 3]

猜你喜欢

转载自blog.csdn.net/Shangxingya/article/details/105892406