1.直接插入排序

核心思想

每一趟从数组中找出最小的元素,“插入”到数组的最前面。

核心代码

//直接插入排序
void InsertSort()
{
    int n=10,i,j;
    for (i=2;i<n;i++)
    {
        if (a[i]<a[i-1]){
            a[0]=a[i]; //哨兵
            for (j=i-1;a[j]>a[0];j--)
            {
                a[j+1]=a[j];
            }
            a[j+1]=a[0];
        }
    }
}

代码思想

第一个循环遍历过的已经排序,未遍历的就是待排序的,不断将下一个待排序的元素与已经排序的元素从后往前依次比较,将排好序的往后挪,最后将待排序元素插入应该在的位置。

举例:

28 19 5 38 22 44

第一趟:5 28 19 38 22 44

第一趟:5 19 28 38 22 44

第三趟:5 19 22 28 38 44

排序完成

2.希尔排序

核心思想

每次设置一个增量dk,一般第一趟n/2,第二趟n/4...以此类推。将每个元素以其后面dk个元素进行比较并排序。比如一共八个元素,第一次增量为4,则第一,第五个元素比较,第二,第六个元素比较...第二次增量为2,则第一,三,五,七比较,第二,四,六,八比较,最后一次增量是1,则每个元素进行比较。

核心代码

//希尔排序
void ShellSort()
{
    int dk,i,j,n=10;
    for (dk=n/2;dk>0;dk/=2)
    {
        for (i=dk+1;i<n;i++)
        {
            if (a[i-dk]>a[i])
            {
                a[0]=a[i];
                for (j=i-dk;a[j]>a[0]&&j>0;j-=dk)
                {
                    a[j+dk]=a[j];
                }
                a[j+dk]=a[0];
            }
        }
    }
}

代码思想

和直接插入排序类似。但是直接插入的增量是1,希尔排序是动态的。

举例

9 0 47 41 40 28 7 1

第一趟:9 0 7 1 40 28 47 41

第二趟:7 0 9 1 40 28 47 41

第三趟:0 1 7 9 28 40 41 47

排序完成

3.总结

稳定性

直接插入排序是稳定的,希尔排序是不稳定的。

效率

空间效率都是O(1)

时间效率:

直接插入排序:最好O(n)(基本有序的情况下) 平均O($n^2$)

希尔排序:一般在O(n^1.3)左右

最后修改:2023 年 12 月 26 日
如果觉得我的文章对你有用,请随意赞赏