算法 排序算法之插入排序--直接插入排序和希尔排序

插入排序

基本思想

从初始有序的子集合开始,不断的把新的元素插入到已经排好序的子集合的合适位置上,使得子集合中数据元素的个数不断增多。当子集合等于集合时,插入排序算法结束。

常用的插入排序有

  • 直接插入排序
  • 希尔排序

直接插入排序

基本思想

顺序的把待排序的数据元素按照大小插入到已排序数据元素子集合的适当位置。子集合的数据元素个数从只有一个开始逐步递增到和集合大小相同时排序完毕

排序过程

这里写图片描述

代码实现

C实现

void InsertSort(DataType a[],int n){
        int i,j;
        DataType temp;

        for (i=0;i<n-1;i++){
            temp = a[i+1];
            j=i;
            while (j>-1&&temp<a[j]){
                a[j+1] = a[j];
                j--;
            }
            a[j+1]=temp;
        }
    }

java代码实现

/**
     * 插入排序
     */
    public static void insertSort(int[] arr) {
        int temp;
        for (int i = 1; i < arr.length; i++) {
            int j = i - 1;
            temp = arr[i];
            while (j >= 0 && arr[j] > temp) {
                arr[j + 1] = arr[j];
                j--;
            }
            arr[j + 1] = temp;
        }
    }

算法分析

  • 最好情况时间复杂度:

    • 集合全部有序,此时内存while循环次数为0,外层for循环每次比较次数为1,整个排序的比较次数n-1,时间复杂度为O(n)
  • 最坏情况时间复杂度

    • 集合逆序 内层while循环次数均为i 时间复杂度O(n^2)
  • 平均时间复杂度

    • 期望时间复杂度为O(n^2)
  • 空间复杂度 O(1)

  • 稳定性

    • 直接插入算法是一种稳定的排序算法

希尔排序

基本思想

  • 把待排序的数据元素分成若干个小组,对同一个小组内的数据元素用直接插入法排序;
  • 小组的个数逐步缩小
  • 当完成了所有元素都在一个组内的排序后排序过程结束

希尔排序又叫做缩小增量排序

排序过程

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

代码实现

C实现

 void ShellSort(DataType a[],int n,int d[],int numOfD){
        int i,j,k,m,span;
        DataType temp;

        for (m=0;m<numOfD;m++){//共numOfD次循环
            span = d[m];//取本次的增量值
            for (k=0;k<span;k++){
                /*组内是直接插入排序 区别是每次不是增1而是增Span*/
                for (i=k;i<n-span;i=i+span){
                    temp = a[i+span];
                    j = i;
                    while (j>-1&&a[j]>=temp){
                        a[j+span] = a[j];
                        j = j-span;
                    }
                    a[j+span] = temp;
                }
            }
        }
    }
public static void shellSort(int[] arr, int[] d) {
        int arrLength = arr.length, dLength = d.length;
        int temp, m;

        for (int i = 0; i < dLength; i++) {
            int span = d[i];//取当前增量值
            for (int j = 0; j < span; j++) {
                for (int k = j; k < arrLength - span; k = k + span) {
                    temp = arr[k+span];
                    m = k;
                    while (m > -1 && arr[m] >= temp) {
                        arr[m + span] = arr[m];
                        m = m - span;
                    }
                    arr[m + span] = temp;
                }
            }
            printArr(arr);
            System.out.println();
        }
    }

算法分析

直接插入排序是两重循环
希尔排序是四重循环 每重循环次数都很小

  • 时间复杂度 O(n(log2n)^2)
  • 空间复杂度O(1)
  • 不稳定的排序算法

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值