QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3167|回复: 0
打印 上一主题 下一主题

[其他资源] 【基于C的排序算法】插入排序之直接插入排序

[复制链接]
字体大小: 正常 放大
杨利霞        

5273

主题

82

听众

17万

积分

  • TA的每日心情
    开心
    2021-8-11 17:59
  • 签到天数: 17 天

    [LV.4]偶尔看看III

    网络挑战赛参赛者

    网络挑战赛参赛者

    自我介绍
    本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。

    群组2018美赛大象算法课程

    群组2018美赛护航培训课程

    群组2019年 数学中国站长建

    群组2019年数据分析师课程

    群组2018年大象老师国赛优

    跳转到指定楼层
    1#
    发表于 2022-9-14 16:31 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    【基于C的排序算法】插入排序之直接插入排序
    9 W3 g; m% _# Z) y$ `4 s2 I% y" M1 T+ Y0 g7 _2 ?8 Q
    前言% J% L+ F, [9 B2 ~+ {. l
    本文基于C语言来分享一波笔者对于排序算法的插入排序中的直接插入排序的学习心得与经验,由于水平有限,纰漏难免,欢迎指正交流。
    3 `( _; y3 ~( d% o1 o$ u; Z% m  ]- u9 `, |' k( [! u8 |/ S- v
    直接插入排序) E7 N) N6 A: r
    ​ 直接插入排序是一种简单的插入排序法,其基本思想是 :
    9 ?$ ?0 f7 |/ h5 I+ g. \& ^  f' U, e" z& y/ @: V- k
    ​ 把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为
    9 Y1 j* C, r4 q% u/ }止,得到一个新的有序序列 。; b* l" j" h( I( u# m7 ]% F' O7 u
    ​ 实际中我们玩扑克牌时,就用了插入排序的思想2 ^! G8 M! ~+ O/ Y1 `* U& F

    8 ^- S" s3 A; e9 t! G
    ' G+ K2 {. T+ y& p
    ( ?$ U* L0 o/ T! p% |$ ~# _​ 当插入第i(i>=1)个元素时,前面的array[0],array[1],…,array[i-1]已经排好序,此时用array的排序码与1 ?) M8 l$ Z2 f# b
    array[i-1],array[i-2],…的排序码顺序进行比较,找到插入位置即将array插入,原来位置上的元素顺序后移。% g9 C" t: F- v" O8 p) ?8 N/ E) k- ^# J

    / T$ [: X6 c9 `升序排列的示例:8 x( k' o8 j0 D/ w, d* a- {; B

    2 \; F* u- j6 K+ s8 C
    & \. s; g8 B$ c4 `, c  i; V+ E2 Q3 I% O& \1 y' W4 ~3 A
    下面以升序排列为例讲解过程:
    1 I, r" h- B. [! B& L$ |/ F, ~+ d, `% x3 T; B( l- q+ o
    ​ 原序列中可以分成两个序列,前面的是已排序的有序序列,用一个下标end标志该序列的尾,初始状态下end是0;后面的是还未排序的序列,用一个tmp变量暂存未排序序列首个元素,实际上是通过tmp = arr[end + 1] 实现的,也就是end指向的下一个元素。为什么要用变量暂存end的下一个元素呢?因为有可能涉及到元素后移,比如说,如果arr[end]要比tmp的值大,根据升序,应该把arr[end]的值后移对吧,那要是直接后移就会覆盖掉arr[end + 1],所以在移动前要先把元素暂存到tmp中。在每一次比较后end要递减一下,向前移动。要是tmp比arr[end]要大该怎么操作呢?这时候就说明找到要插入的位置了,把tmp的值插入到arr[end + 1]即可。
    ( q9 o1 G% W5 }8 s/ P( z8 p5 o

    8 D/ `0 H& ^0 w$ d7 A4 W) ^+ r3 \' E: K; s- ?* r1 [4 W$ n
    ​ 可以看出,直接插入排序不可能只有一轮,像前面讲的过程就是一轮的过程,结果就是把未排序序列的首元素插入到了已排序序列中并保持原来的顺序,正如把刚摸到的一张牌按顺序插入到你的手牌中。实际上,一开始序列是全部未排序的,我们可以把第一个元素作为已排序元素,也就是说已排序序列一开始只有一个元素,end值就为0,后面的元素就全部都是未排序序列的了。
    / t( p& F% b8 f; ]) G  c9 w. O, C) ~, D

    - u2 D; o# M; }5 X1 Q8 v/ D
    ! [2 u: l, o6 {( E​ 也就是说要将整个原序列排好序的话要让已排序序列拓展至整个原序列,也就是end要不断增加到size - 1(size是数组元素个数),end值为size - 1时结束,所以还要外套一个循环。- S1 I! k, m3 t7 _! |+ H
    ; N4 u) A+ Z. ^4 |3 l2 [
    void InsertSort(int* arr, int sz): V' s$ z8 I6 c7 Z8 c, ?5 P1 |* @
    {$ ^6 r+ Y' L! D) @* R3 c. T
            assert(arr);, E7 K- s: Y/ f: X

    ; _& v1 h: G. j0 v        for (int i = 0; i < sz - 1; ++i)//i的取值就是end的取值,end最多取到sz-2算有效,当它取到sz-1时就该结束循环了" _9 ^! Q# |3 o& `% |' u
            {
    6 Z. y: I# S4 `, _; ?! n! I                //单轮排序
    , M& i" G0 E1 B& Z( W                int end = i;) A$ n- W0 z/ w5 n8 M
                    int tmp = arr[end + 1];9 `* C# Z9 M" Z2 d& ~! A* }
                    while (end >= 0)//为什么要>=0呢?可不可以>0?
    " }5 Q: }5 D$ F( Q                {. ]" f. |; D4 D7 f7 f
                            //要排升序               
    & g( M5 n: z! L/ J6 K0 U0 b# w. ]) y                        if (tmp < arr[end])& [8 f! W: b( ?" |
                            {3 r5 D0 x! r2 o: J& `
                                    arr[end + 1] = arr[end];
    - J  S) g, t- [4 [, o                                --end;6 R6 y) o. T; ~5 L1 k$ z0 s- k
                            }
    * L7 q+ N3 n! v7 @  w                        else! O1 x) s' M( b: S+ s# C  y
                            {                               
    * z+ l# q& c1 `% ~' y* P7 N                                break;# q# ~) Q+ C1 k. N* v3 y# e
                            }                3 q4 ]" {; G( B1 C0 i" k
                    }/ ?. \" i! @) G3 G/ J% }) ^# N
                    arr[end + 1] = tmp;
    9 r; D3 I2 H1 V8 F; H& c        }. j. `0 a8 v. n: v: ~6 q" D: }
    }& O& b# ?- f$ Y+ `) C

    ' H3 ?& t5 m: |1' j! e& n, K  O  n. k3 p$ b
    2/ k; a  A! m' P8 B+ T' F) @
    3, r5 m: T( Y! i2 f" o3 @: D
    4. N. I# R4 b" G
    5! H% d4 E$ E, H' N8 i
    68 V1 a/ e. L* \) b/ x  N
    7% C2 P0 M3 w+ f1 \; p& z( I
    85 U) a' U6 v% ^0 ]
    9
    ; o" y1 ?& U' r2 p100 h5 a& B) H: b- i' p
    11: G5 I. A1 n, [/ |  T
    12
    & p$ `7 h5 m7 U& g; C13
    / Q% N7 A( A! F, Q14  r6 e6 _8 ~: H) a7 O( G; h9 o! p7 D( \! Y
    15
    & H8 ^- y- |" H% `1 s2 _161 [/ N5 K6 m8 ?+ K$ K) n
    17
    $ @" `1 s1 z  w2 S) M. M186 G# Y0 i  ~  G3 t
    19
    ) g+ {# V0 E9 D7 r! D207 w# P# W' ^& i& O" b8 j
    21* L/ v) d$ Y: g" |# m# E1 ~8 Y, W8 x
    22
    2 p+ Z( e4 x; k& T& G$ ~5 u6 C23
    , e7 |8 \- X5 k0 i+ s/ d7 n  g24
    & W! u: h( e0 c6 H: o7 N25
    / X. k. b6 _! Q. p( s1 g( Q! v​ end可以为0,因为有可能tmp的值比arr[0]还小,那就得让原来的arr[0]后移,把tmp放到arr[0]的位置。$ [& l; ]! R* H0 a" H- W" Y

    ' l4 g8 F& u! G0 M4 Q# e; u: h1 ~( Q2 _

    4 {( F$ p& B6 e直接插入排序的特性总结:
    ; C! R1 J, ?+ p+ A! I- Y" `3 Y; z9 J  Y" w9 E
    元素集合越接近有序,直接插入排序算法的时间效率越高,最好情况下(有序)时间复杂度为O(n)
    - j- r4 t. x& g1 P时间复杂度:O(n2)
    ! _: T! `2 t# J$ V空间复杂度:O(1),它是一种稳定的排序算法
    2 y( _" T/ B  I$ L1 @( z8 Z) Z稳定性:稳定1 t, n' f0 i3 }0 V9 O
    感谢观看,你的支持就是对我最大的鼓励~* ]% a# j, d8 b. Q$ s  t
    ————————————————
      i  w% ?8 J0 ^* N/ Q版权声明:本文为CSDN博主「桦秋静」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。7 t2 g2 q- P6 }! {( I3 L) m6 Q! R  e
    原文链接:https://blog.csdn.net/weixin_61561736/article/details/126796593% }2 w# j, P. \% w
    ! K# h& W# m3 c1 V, j
    9 i! P4 a& ]  l6 |& [9 U
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-4-10 00:38 , Processed in 1.328644 second(s), 51 queries .

    回顶部