初级排序算法(选择、插入、希尔)

初级排序算法

选择排序

选择排序,就是每次都从待排序序列中获得关心的值的最小的项,并将其与第一个项交换,依次循环,直到所有的项都排序完成。

/**
 *功能描述:传入一个 int 类型的数组,进行排序,flag : true 升序,false 降序
 *@param  arr the array that needs to be sorted.
 *@author Jason
 *Date 2020-07-28 16:32
 */
 private static int [] selectSort(int [] arr, boolean flag) {
        for (int i = 0 ; i < arr.length - 1 ; i ++ ) {
            int index = i;
            for (int j = i + 1 ; j < arr.length ; j ++ ) {
                if(flag == (arr[index] > arr[j])){
                    index = j;
                }
            }
            if(i != index){
                int tmp = arr[i];
                arr[i] = arr[index];
                arr[index] = tmp;
            }
        }
        return arr;
    }

img

这个排序算法是比较好理解的,通过上图也可以比较直观地看出排序的过程。

下面来看看该算法的两个特性:

1.运行的时间只和传入的数组的长度有关,与数组本身是否有序无关

在每次寻找最小元素的时候,都会对数组扫描一遍,并不会因为元素是否有序而减少扫描次数。

2.数组元素的交换次数与数组的长度是线性关系

每次扫描找到一个最小的元素时,都会进行一次交换。

插入排序

上述的选择排序算法中,对于一个接近有序的数组排序的时候,仍然是需要和乱序一样的排序时间,这就是一个可以优化的地方,那有没有一种排序方法,可以对一个接近有序的序列快速地排序?

答案是有的: 插入排序

我们这里和 选择排序做个对比:

  • 和选择排序一样,他也是需要比较的,而且在正在排序的序列索引的左侧部分是一个已经有序的序列了,但是插入排序,左侧元素的具体位置,目前还不能确定,有可能在后续的过程发生更改,当排序的索引位于数组的右侧时,排序完成。
  • 与选择排序不同的是,插入排序所需要的时间与序列的原本顺序有直接的关系,对于一个接近有序的序列使用插入排序会比乱序和逆序的快得多。
private static int [] insertSort(int[] arr, boolean flag) {
        for (int i = 0 ; i < arr.length - 1; i ++ ) {
            int tmp = arr[i+1];
            for (int j = 0 ; j <= i ; j ++ ) {
                if(flag == (arr[j] > arr[i + 1])){
                    if (i + 1 - j >= 0)
                        System.arraycopy(arr, j, arr, j + 1, i + 1 - j);
                    arr[j] = tmp;
                }
            }
        }
        return arr;
}

img

希尔排序

希尔排序是一个基于插入排序的一种快速排序算法。对于一般的插入排序算法而言,较大规模的乱序数组的排序就会很慢,因为它只会交换相邻的数组元素,元素只能一点一点地移动到一侧。希尔排序就不再是交换相邻的元素,而是不相邻的元素,对数组进行局部的排序,是的整个数组局部有序,随着间隔的减小,最后对整个数组进行一次插入排序,便可以完成对整个数组的排序。

初级排序算法(选择、插入、希尔)_第1张图片

上图就是以一个 gap=4为例,将子序列排出,对各个子序列进行插入排序,之后便会将 gap的值减小,直到 1 ,最后一次插入排序后,整个数组就已经排好序了。

初级排序算法(选择、插入、希尔)_第2张图片

/**
 *功能描述:传入一个 int 类型的数组,进行排序,flag : true 升序,false 降序
 *@param  arr the array that needs to be sorted.
 *@author Jason
 *Date 2020-07-28 16:32
 */
private static int [] shellSort(int [] arr, boolean flag) {
    int gap = arr.length >> 1;
    while (gap > 0) {
        for (int i = gap; i < arr.length; i ++ ) {
            int tmp = arr[i];
            int index = i - gap;
            while (index >= 0 && flag == (arr[index] > tmp) ) {
                arr[index + gap] = arr[index];
                index -= gap;
            }
            arr[index + gap] = tmp;
        }
        gap = gap >> 1;
    }
    return arr;
}

希尔排序比选择排序和插入排序都要快,数组越大,优势越明显。

欢迎关注公众号

个人公众号会持续推送数据结构方面的文章或资源~~

你可能感兴趣的:(数据结构和算法,数据结构,算法)