有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这个时候就要用到一种新的排序方法——插入排序插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为O(n^2)。是稳定的排序方法。插入算法把要排序的数组分成两部分:第一部分包含了这个数组的所有元素,但将最后一个元素除外(让数组多一个空间才有插入的位置),而第二部分就只包含这一个元素(即待插入元素)。在第一部分排序完成后,再将这个最后元素插入到已排好序的第一部分中。

插入排序的基本思想是:每步将一个待排序的纪录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。

希尔排序是一种插入排序算法,它出自D.L.Shell,因此而得名。Shell排序又称作缩小增量排序。

算法分析

         插入排序的思想:
        从第二个元素开始往后,依次选择哨兵元素和前面的元素比较,如果前一个元素大于该哨兵元素(从小到大排序),则把前面那个元素移动到后一个位置;继续往前比较,直到找某个元素不大于该哨兵元素,则把哨兵元素插入到位置上;

        插入排序的步骤:
       1、第二个元素开始外后选择一个哨兵元素;
       2、让哨兵元素和前面的元素进行比较,找到合适的位置插入;
       3、循环上面两步,直到选择完所有元素;

        shell排序的思想:
       shell排序是相当于把一个数组中的所有元素分成几部分来排序;先把几个小部分的元素排序好,让元素大概有个顺序,最后再全面使用插入排序。一般最后一次排序都是和上面的插入排序一样的;
       
       shell排序的步骤:
       比如:
        数组有10个元素,增量 d = 5;则比较元素为:array[0]    array[0+d]    array[0+2d]  array[0+3d];(当然 d 会改变的,d = d/2  或者 d = d -2)
       第一次  d = 5  比较的元素为:array[0]  , array[5]  
       第二次  d = d/2 = 2 比较元素为:array[0]  , array[2]  , array[4] , array[6] , array[8]
       第三次  d = d/2 = 1 比较元素为:从array[0] 到  array[9]

        其实上面的插入排序可以看作是 增量 d = 1的shell排序;当然同理,shell排序 最后增量 d = 1时, 就是插入排序了;

代码实现

#include<stdio.h>#include<stdlib.h>void print_array(int *array, int length){int index = 0;printf("array:\n");for(; index < length; index++){printf(" %d,", *(array+index));}   printf("\n\n");}void insertSort(int *array, int length){int index_i, index_j, tmp;for (index_i = 1; index_i < length; index_i++){ // 从第二个元素往后得到哨兵元素tmp = array[index_i];for (index_j = index_i - 1; index_j >= 0 ; index_j--){ // 和前面有序的元素进行比较 调整if (array[index_j] > tmp) array[index_j + 1] = array[index_j];else break;}   array[index_j + 1] = tmp;// 找到合适的位置插入}   }void shellSort(int *array, int length){int d = 5;int i , j, tmp;while(d){ // 判断增量for ( i = d; i < length; i = i + d){ // 从第一个增量值往后  得到哨兵元素 tmp = array[i];for (j = i -d ; j >= 0; j = j - d){ // 和前面有序的元素进行调整if (array[j] > tmp) array[j+d] = array[j];else break;}array[j+d] = tmp;}d = d/2; // 缩小增量的值}}int main(void){//int array[] = {12, 1, 32, 201, 9987, 5, 10, 10090, 123, 453};int array[] = {2, 1, 3, 201, 987, 5, 10, 90, 13, 45};int length = (sizeof(array)) / (sizeof(array[1]));print_array(array, length);insertSort(array, length);print_array(array, length);printf("\n\n======================\n\n");shellSort(array, length);print_array(array, length);return 0;}

运行结果

时间复杂度

         插入排序的时间复杂度:

         在最好的情况下(元素已经排好顺序):那么只需要循环 n-1  次就可以了,时间复杂度 O(n)

在最差的情况下 (元素是逆序的):要循环调整次数: [ n * (n-1) ] / 2 ,时间复杂度为 O(n ^ 2)

        平均时间复杂度为:O(n ^ 2)

shell排序的时间复杂度:   

        shell排序的时间复杂度是根据选中的 增量d 有关的,所以分析shell排序的时间复杂度是个比较麻烦的事;这里只给出答案,不推算了;

         在最优的情况下,时间复杂度为:O(n ^ (1.3) )   (元素已经排序好顺序)

         在最差的情况下,时间复杂度为:O(n ^ 2);


空间复杂度

    空间复杂度都为:O(1);

        转载请注明作者和原文出处,原文地址:http://blog.csdn.net/yuzhihui_no1/article/details/44647595
        若有不正确之处,望大家指正,共同学习!谢谢!!!

排序算法之 插入排序、希尔(shell)排序 及其时间复杂度和空间复杂度相关推荐

  1. 常见排序算法的最好、最坏、平均时间复杂度以及空间复杂度

    文章目录 思考 前言 如何分析一个排序算法? 排序算法的执行效率 排序算法的内存消耗 排序算法的稳定性 如何选择合适的排序算法? 如何优化快速排序? 解答思考题 参考链接 思考 为什么插入排序比冒泡排 ...

  2. 排序算法 | 希尔shell排序,算法的图解、实现、复杂度和稳定性分析

    希尔shell排序 1.希尔排序--定义 2.希尔排序--步骤描述 3.希尔排序--算法实现 4.希尔排序--复杂度.稳定性分析 1.希尔排序--定义 希尔排序按其设计者希尔(Donald Shell ...

  3. 数据结构—排序算法总结(插入排序、希尔排序、选择排序、堆排序、冒泡排序、快速排序、合并排序、计数排序)

    *排序 所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作. 稳定性 在待排序的数组中,如果出现多个相同的关键字,例如:98751555512,中出现重复的数字,在 ...

  4. java语言冒泡排序法_Java实现八个常用的排序算法:插入排序、冒泡排序、选择排序、希尔排序等...

    本文实现了八个常用的排序算法:插入排序.冒泡排序.选择排序.希尔排序 .快速排序.归并排序.堆排序和LST基数排序 首先是EightAlgorithms.java文件,代码如下: import jav ...

  5. 【Java】八个常用的排序算法:插入排序、冒泡排序、选择排序、希尔排序 、快速排序、归并排序、堆排序和LST基数排序

    这篇文章主要介绍了Java如何实现八个常用的排序算法:插入排序.冒泡排序.选择排序.希尔排序 .快速排序.归并排序.堆排序和LST基数排序,需要的朋友可以参考下 本文实现了八个常用的排序算法:插入排序 ...

  6. 对以下6种常用的内部排序算法进行比较:起泡排序、直接插入排序、简单选择排序、快速排序、希尔排序、堆排序。

    题目要求: (1)对以下6种常用的内部排序算法进行比较:起泡排序.直接插入排序.简单选择排序.快速排序.希尔排序.堆排序. (2)待排序表的表长不小于100:其中的数据要用伪随机数产生程序产生:至少要 ...

  7. 插入排序算法 java_排序算法实现-插入排序(Java版本)

    原标题:排序算法实现-插入排序(Java版本) 插入排序(英语:Insertion Sort)是一种简单直观的排序算法.它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到 ...

  8. 排序算法 | 直接插入排序算法的图解、实现、复杂度和稳定性分析

    排序算法 | 直接插入排序算法的图解.实现.复杂度和稳定性分析 目录 1.直接插入排序定义 2.直接插入排序,步骤说明 3.动态图演示 4.代码实现,运行结果 5.算法分析 ① 时间复杂度分析 ② 空 ...

  9. python实现排序算法_python实现·十大排序算法之插入排序(Insertion Sort)

    简介 插入排序(Insertion Sort)是一种简单直观的排序算法.它的工作原理是:通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入. 算法实现步骤 从第一个元素开 ...

最新文章

  1. .Net Core MVC初学习
  2. android SQL 语句
  3. Numpy-矩阵的运算
  4. 201712-2放学
  5. MySQL 主从同步故障处理-小记
  6. python queue windows_python Queue模块
  7. 数据结构—链表-单链表应用-拆分链表
  8. Flink 1.9 : Wordcount报错:ClassNotFoundException: yarn.exceptions.YarnException
  9. 模式代码 java中aes_深入浅出:Java中的代理模式
  10. redis3.0搭建分布式集群
  11. 图文解说:Discuz论坛基础设置第一弹
  12. linux下无线网卡的ioctl 接口
  13. vscode安装旧版本插件_vscode安装和安装插件
  14. 使用Arcmap创建企业级地理数据库失败,无法连接到数据库
  15. c++语言常量,C++常量(constant)
  16. 洛谷 P3403 跳楼机 题解
  17. 大自然Windows XP日文版镜像
  18. 学计算机游戏与动漫好吗,学习计算机动漫与游戏制作前途如何?
  19. HTML5 实现给Text文本框中加入图片
  20. html 网页背景图片根据屏幕大小CSS自动缩放

热门文章

  1. AndroidStudio安装apk到vivo手机时提示安装失败
  2. Python手把手实现远程控制桌面
  3. 每日一道算法题 拿金币(蓝桥杯练习系统)简单的dp算法
  4. Mac下Qt for android 环境配置
  5. 阿里安全专家BlackHat和DEFCON现场演示:一分钟越狱iOS 11.4
  6. Rainbow Fart安装及设置其他语音包
  7. 常用git 命令备忘
  8. RecyclerView超级万能适配器(多布局、head、foot、下拉刷新、上拉自动更多、滑动删除)
  9. 智慧数字经营要怎么代理加盟? 本文详解。
  10. 汇编 eax test jnz jz 等组合连用的总结